diff --git a/alib2algo/src/stringology/matching/SequenceMatchingAutomaton.cpp b/alib2algo/src/stringology/matching/SequenceMatchingAutomaton.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce8e5b637092de0f262a3f274a9a871d23197a86 --- /dev/null +++ b/alib2algo/src/stringology/matching/SequenceMatchingAutomaton.cpp @@ -0,0 +1,19 @@ +/* + * ExactMatchingAutomaton.cpp + * + * Created on: 9. 2. 2014 + * Author: Jan Travnicek + */ + +#include "SequenceMatchingAutomaton.h" +#include <registration/AlgoRegistration.hpp> + +namespace stringology { + +namespace matching { + +auto SequenceMatchingAutomatonLinearString = registration::AbstractRegister < SequenceMatchingAutomaton, automaton::NFA < DefaultSymbolType, unsigned >, const string::LinearString < > & > ( SequenceMatchingAutomaton::construct ); + +} /* namespace matching */ + +} /* namespace stringology */ diff --git a/alib2algo/src/stringology/matching/SequenceMatchingAutomaton.h b/alib2algo/src/stringology/matching/SequenceMatchingAutomaton.h new file mode 100644 index 0000000000000000000000000000000000000000..0f9775e6ae4911753cbba874a7fcb0704cc0b2a9 --- /dev/null +++ b/alib2algo/src/stringology/matching/SequenceMatchingAutomaton.h @@ -0,0 +1,60 @@ +/* + * ExactMatchingAutomaton.h + * + * Created on: 27. 3. 2017 + * Author: Tomas Capek + */ + +#ifndef _SEQUENCE_MATCHING_AUTOMATON_H__ +#define _SEQUENCE_MATCHING_AUTOMATON_H__ + +#include <automaton/FSM/NFA.h> +#include <string/LinearString.h> + +namespace stringology { + +namespace matching { + +class SequenceMatchingAutomaton { +public: + /** + * Create automaton. + * @return sequence matching automaton. + */ + template < class SymbolType > + static automaton::NFA < SymbolType, unsigned int > construct(const string::LinearString < SymbolType > & pattern); +}; + +template < class SymbolType > +automaton::NFA < SymbolType, unsigned int > SequenceMatchingAutomaton::construct(const string::LinearString < SymbolType > & pattern) { + automaton::NFA <SymbolType, unsigned int> result(0); + result.setInputAlphabet(pattern.getAlphabet()); + + for ( const SymbolType & symbol: pattern.getAlphabet()) { + result.addTransition(0, symbol, 0); + } + + for ( unsigned int i=0; i<pattern.getContent().size(); i++) { + auto from = i; + auto to = i+1; + + result.addState(to); + result.addTransition(from, pattern.getContent()[i], to); + + for( const SymbolType & symbol: pattern.getAlphabet()) { + if (symbol != pattern.getContent()[i]) { + result.addTransition(from, symbol, from); + } + } + } + + result.addFinalState(pattern.getContent().size()); + + return result; +} + +} /* namespace matching */ + +} /* namespace stringology */ + +#endif /* _SEQUENCE_MATCHING_AUTOMATON_H__ */ diff --git a/alib2algo/test-src/stringology/matching/SequenceMatchingAutomatonTest.cpp b/alib2algo/test-src/stringology/matching/SequenceMatchingAutomatonTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..94d9416acc80953c72fd0093d4c5dd8e8bda42ac --- /dev/null +++ b/alib2algo/test-src/stringology/matching/SequenceMatchingAutomatonTest.cpp @@ -0,0 +1,45 @@ +#include <stringology/matching/SequenceMatchingAutomaton.h> +#include <automaton/FSM/NFA.h> +#include <string/LinearString.h> + +#include "SequenceMatchingAutomatonTest.h" + + +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION ( SequenceMatchingAutomatonTest, "stringology" ); +CPPUNIT_TEST_SUITE_REGISTRATION ( SequenceMatchingAutomatonTest ); + +void SequenceMatchingAutomatonTest::testSimpleConstruction() { + ext::set<char> alphabet{'a', 'b', 'c', 'd'}; + string::LinearString <char> input_string(alphabet, ext::vector<char>{'a', 'b', 'c'}); + auto resulting_automata = stringology::matching::SequenceMatchingAutomaton::construct(input_string); + + automaton::NFA <char, unsigned int> test(0); + test.setInputAlphabet(ext::set<char>{'a', 'b', 'c', 'd'}); + test.setStates(ext::set<unsigned int> {0, 1, 2, 3}); + test.addFinalState(3); + + test.addTransition(0, 'a', 0); // initial loop over whole alphabet + test.addTransition(0, 'b', 0); + test.addTransition(0, 'c', 0); + test.addTransition(0, 'd', 0); + + test.addTransition(0, 'a', 1); // part of a sequence + + test.addTransition(1, 'a', 1); + test.addTransition(1, 'c', 1); + test.addTransition(1, 'd', 1); + + test.addTransition(1, 'b', 2); // part of a sequence + + test.addTransition(2, 'a', 2); + test.addTransition(2, 'b', 2); + test.addTransition(2, 'd', 2); + + test.addTransition(2, 'c', 3); // part of a sequence + + CPPUNIT_ASSERT(resulting_automata == test); +} + +void SequenceMatchingAutomatonTest::setUp() { } + +void SequenceMatchingAutomatonTest::tearDown() { } diff --git a/alib2algo/test-src/stringology/matching/SequenceMatchingAutomatonTest.h b/alib2algo/test-src/stringology/matching/SequenceMatchingAutomatonTest.h new file mode 100644 index 0000000000000000000000000000000000000000..cb49f2c1af7ac0fa1d6fc98f9b74033367937e80 --- /dev/null +++ b/alib2algo/test-src/stringology/matching/SequenceMatchingAutomatonTest.h @@ -0,0 +1,17 @@ +#ifndef SEQUENCE_MATCHING_AUTOMATA_TEST_H_ +#define SEQUENCE_MATCHING_AUTOMATA_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class SequenceMatchingAutomatonTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(SequenceMatchingAutomatonTest); + CPPUNIT_TEST(testSimpleConstruction); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp ( ); + void tearDown ( ); + + void testSimpleConstruction(); +}; +#endif //SEQUENCE_MATCHING_AUTOMATA_TEST_H_