From 3acd192c23462e7a904007830524375b14af1278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Sat, 1 Nov 2014 22:25:41 +0100 Subject: [PATCH] algo: Stringology: Suffix Trie construction Conflicts: astringology2/src/astringology.cpp Conflicts: astringology2/src/astringology.cpp --- .../src/stringology/indexing/SuffixTrie.cpp | 47 +++ .../src/stringology/indexing/SuffixTrie.h | 50 +++ .../src/indexes/suffixTrie/SuffixTrie.cpp | 5 + alib2data/src/indexes/suffixTrie/SuffixTrie.h | 1 + .../src/indexes/suffixTrie/SuffixTrieNode.cpp | 30 ++ .../src/indexes/suffixTrie/SuffixTrieNode.h | 8 + astringology2/src/astringology.cpp | 303 ++++++++++-------- 7 files changed, 302 insertions(+), 142 deletions(-) create mode 100644 alib2algo/src/stringology/indexing/SuffixTrie.cpp create mode 100644 alib2algo/src/stringology/indexing/SuffixTrie.h diff --git a/alib2algo/src/stringology/indexing/SuffixTrie.cpp b/alib2algo/src/stringology/indexing/SuffixTrie.cpp new file mode 100644 index 0000000000..08c1721e95 --- /dev/null +++ b/alib2algo/src/stringology/indexing/SuffixTrie.cpp @@ -0,0 +1,47 @@ +/* + * SuffixTrie.cpp + * + * Created on: 1. 11. 2014 + * Author: Tomas Pecka + */ + +#include "SuffixTrie.h" + +#include <indexes/suffixTrie/SuffixTrie.h> + +#include <exception/AlibException.h> +#include <string/LinearString.h> +#include <string/Epsilon.h> + +namespace stringology { + +namespace indexing { + +indexes::SuffixTrie SuffixTrie::construct ( const string::String & string ) { + return getInstance ( ).dispatch ( string.getData ( ) ); +} + +indexes::SuffixTrie SuffixTrie::construct ( const string::LinearString & w ) { + indexes::SuffixTrie res ( w.getAlphabet ( ) ); + + for ( unsigned int i = 0; i < w.getContent ( ).size ( ); i++ ) { + unsigned int k = i; + indexes::SuffixTrieNode * n = & res.getRoot ( ); + + while ( k < w.getContent ( ).size ( ) && n->hasChild ( w.getContent ( )[k] ) ) + n = & n->getChild ( w.getContent ( )[k++] ); + + for ( ; k < w.getContent ( ).size ( ); k++ ) { + n = & n->addChild ( w.getContent ( )[k], indexes::SuffixTrieNode { { } + } ); + } + } + + return res; +} + +auto SuffixTrieLinearString = SuffixTrie::RegistratorWrapper < indexes::SuffixTrie, string::LinearString > ( SuffixTrie::getInstance ( ), SuffixTrie::construct ); + +} /* namespace indexing */ + +} /* namespace stringology */ diff --git a/alib2algo/src/stringology/indexing/SuffixTrie.h b/alib2algo/src/stringology/indexing/SuffixTrie.h new file mode 100644 index 0000000000..0f8f9fb2b1 --- /dev/null +++ b/alib2algo/src/stringology/indexing/SuffixTrie.h @@ -0,0 +1,50 @@ +/* + * SuffixTrie.h + * + * Created on: 1. 11. 2014 + * Author: Tomas Pecka + */ + +#ifndef SUFFIX_TRIE_H_ +#define SUFFIX_TRIE_H_ + +#include <indexes/suffixTrie/SuffixTrie.h> +#include <string/String.h> +#include <string/LinearString.h> +#include <common/multipleDispatch.hpp> + +namespace stringology { + +namespace indexing { + +/** + * Constructs suffix trie for given string. + * + * Source: Lectures MI-EVY (CTU in Prague), Year 2014, Lecture 3, slide 4 + */ + +class SuffixTrie : public std::SingleDispatch < indexes::SuffixTrie, string::StringBase > { +public: + /** + * Creates suffix trie + * @param string string to construct suffix trie for + * @return automaton + */ + static indexes::SuffixTrie construct ( const string::String & string ); + + static indexes::SuffixTrie construct ( const string::LinearString & string ); + +public: + static SuffixTrie & getInstance ( ) { + static SuffixTrie res; + + return res; + } + +}; + +} /* namespace indexing */ + +} /* namespace stringology */ + +#endif /* SUFFIX_TRIE_H_ */ diff --git a/alib2data/src/indexes/suffixTrie/SuffixTrie.cpp b/alib2data/src/indexes/suffixTrie/SuffixTrie.cpp index ac32c50d05..9c54039524 100644 --- a/alib2data/src/indexes/suffixTrie/SuffixTrie.cpp +++ b/alib2data/src/indexes/suffixTrie/SuffixTrie.cpp @@ -20,6 +20,11 @@ namespace indexes { +SuffixTrie::SuffixTrie ( std::set < alphabet::Symbol > alphabet ) { + this->alphabet = std::move ( alphabet ); + this->tree = new SuffixTrieNode ( { } ); +} + SuffixTrie::SuffixTrie ( std::set < alphabet::Symbol > alphabet, SuffixTrieNode tree ) { this->alphabet = std::move ( alphabet ); this->tree = NULL; diff --git a/alib2data/src/indexes/suffixTrie/SuffixTrie.h b/alib2data/src/indexes/suffixTrie/SuffixTrie.h index dd9392dd1b..f2d7139e78 100644 --- a/alib2data/src/indexes/suffixTrie/SuffixTrie.h +++ b/alib2data/src/indexes/suffixTrie/SuffixTrie.h @@ -37,6 +37,7 @@ public: */ virtual ObjectBase * plunder ( ) &&; + explicit SuffixTrie ( std::set < alphabet::Symbol > alphabet ); explicit SuffixTrie ( std::set < alphabet::Symbol > alphabet, SuffixTrieNode tree ); explicit SuffixTrie ( SuffixTrieNode tree ); diff --git a/alib2data/src/indexes/suffixTrie/SuffixTrieNode.cpp b/alib2data/src/indexes/suffixTrie/SuffixTrieNode.cpp index 8002bbfcef..edef4014ea 100644 --- a/alib2data/src/indexes/suffixTrie/SuffixTrieNode.cpp +++ b/alib2data/src/indexes/suffixTrie/SuffixTrieNode.cpp @@ -77,6 +77,36 @@ const std::map < alphabet::Symbol, SuffixTrieNode * > & SuffixTrieNode::getChild return children; } +SuffixTrieNode & SuffixTrieNode::getChild ( const alphabet::Symbol & symbol ) { + std::map < alphabet::Symbol, SuffixTrieNode * >::const_iterator iter = children.find ( symbol ); + + if ( iter == children.end ( ) ) throw exception::AlibException ( "child does not exist" ); + + return * iter->second; +} + +const SuffixTrieNode & SuffixTrieNode::getChild ( const alphabet::Symbol & symbol ) const { + std::map < alphabet::Symbol, SuffixTrieNode * >::const_iterator iter = children.find ( symbol ); + + if ( iter == children.end ( ) ) throw exception::AlibException ( "child does not exist" ); + + return * iter->second; +} + +bool SuffixTrieNode::hasChild ( const alphabet::Symbol & symbol ) const { + if ( children.find ( symbol ) == children.end ( ) ) return false; + + return true; +} + +SuffixTrieNode & SuffixTrieNode::addChild ( alphabet::Symbol symbol, SuffixTrieNode node ) { + std::map < alphabet::Symbol, SuffixTrieNode * >::iterator iter = children.find ( symbol ); + + if ( iter != children.end ( ) ) throw exception::AlibException ( "child already exist" ); + + return * children.insert ( std::make_pair ( std::move ( symbol ), new SuffixTrieNode ( std::move ( node ) ) ) ).first->second; +} + SuffixTrieNode * SuffixTrieNode::getParent ( ) { return parent; } diff --git a/alib2data/src/indexes/suffixTrie/SuffixTrieNode.h b/alib2data/src/indexes/suffixTrie/SuffixTrieNode.h index 68206812d9..2021854731 100644 --- a/alib2data/src/indexes/suffixTrie/SuffixTrieNode.h +++ b/alib2data/src/indexes/suffixTrie/SuffixTrieNode.h @@ -74,6 +74,14 @@ public: */ const std::map < alphabet::Symbol, SuffixTrieNode * > & getChildren ( ); + SuffixTrieNode & getChild ( const alphabet::Symbol & symbol ); + + const SuffixTrieNode & getChild ( const alphabet::Symbol & symbol ) const; + + bool hasChild ( const alphabet::Symbol & symbol ) const; + + SuffixTrieNode & addChild ( alphabet::Symbol symbol, SuffixTrieNode node ); + SuffixTrieNode * getParent ( ); const SuffixTrieNode * getParent ( ) const; diff --git a/astringology2/src/astringology.cpp b/astringology2/src/astringology.cpp index 9981dc54d4..ae38f2e558 100644 --- a/astringology2/src/astringology.cpp +++ b/astringology2/src/astringology.cpp @@ -24,218 +24,237 @@ #include <stringology/exact/ExactNondeterministicSubsequenceAutomaton.h> #include <stringology/exact/ExactMultiNondeterministicSubsequenceAutomaton.h> #include <stringology/exact/BorderArray.h> +#include <stringology/indexing/SuffixTrie.h> -int main(int argc, char* argv[]) { +int main ( int argc, char * argv[] ) { try { - TCLAP::CmdLine cmd("Stringology algorithm access binary", ' ', "0.01"); + TCLAP::CmdLine cmd ( "Stringology algorithm access binary", ' ', "0.01" ); - std::vector<std::string> allowed; - allowed.push_back("exactMatchingAutomaton"); - allowed.push_back("exactFactorAutomaton"); - allowed.push_back("exactSubsequenceAutomaton"); - allowed.push_back("exactNondeterministicSubsequenceAutomaton"); - allowed.push_back("exactMultiNondeterministicSubsequenceAutomaton"); - allowed.push_back("exactFactorMatch"); - allowed.push_back("boyerMooreHorspool"); - allowed.push_back("borderArray"); - TCLAP::ValuesConstraint<std::string> allowedVals( allowed ); + std::vector < std::string > allowed; + allowed.push_back ( "exactMatchingAutomaton" ); + allowed.push_back ( "exactFactorAutomaton" ); + allowed.push_back ( "exactSubsequenceAutomaton" ); + allowed.push_back ( "exactNondeterministicSubsequenceAutomaton" ); + allowed.push_back ( "exactMultiNondeterministicSubsequenceAutomaton" ); + allowed.push_back ( "exactFactorMatch" ); + allowed.push_back ( "boyerMooreHorspool" ); + allowed.push_back ( "borderArray" ); + allowed.push_back ( "suffixTrie" ); + TCLAP::ValuesConstraint < std::string > allowedVals ( allowed ); - TCLAP::ValueArg<std::string> algorithm( "a", "algorithm", "Execute algorithm", false, "exactFactorMatch", &allowedVals); - cmd.add(algorithm); + TCLAP::ValueArg < std::string > algorithm ( "a", "algorithm", "Execute algorithm", false, "exactFactorMatch", & allowedVals ); + cmd.add ( algorithm ); - TCLAP::MultiArg<std::string> subject( "s", "subject", "Subject string from file", false, "file"); - cmd.add( subject ); + TCLAP::MultiArg < std::string > subject ( "s", "subject", "Subject string from file", false, "file" ); + cmd.add ( subject ); - TCLAP::MultiArg<std::string> pattern( "p", "pattern", "Pattern string from file", false, "file"); - cmd.add( pattern ); + TCLAP::MultiArg < std::string > pattern ( "p", "pattern", "Pattern string from file", false, "file" ); + cmd.add ( pattern ); - TCLAP::SwitchArg measure( "m", "measure", "Measure times", false); - cmd.add( measure ); + TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false ); + cmd.add ( measure ); - TCLAP::SwitchArg verbose( "v", "verbose", "Be verbose", false); - cmd.add( verbose ); + TCLAP::SwitchArg verbose ( "v", "verbose", "Be verbose", false ); + cmd.add ( verbose ); - cmd.parse(argc,argv); + cmd.parse ( argc, argv ); int needPattern = 0; int needSubject = 0; - if( algorithm.getValue() == "exactFactorMatch") { + + if ( algorithm.getValue ( ) == "exactFactorMatch" ) { needPattern = needSubject = 1; - } else if( algorithm.getValue() == "boyerMooreHorspool") { + } else if ( algorithm.getValue ( ) == "boyerMooreHorspool" ) { needPattern = needSubject = 1; - } else if( algorithm.getValue() == "exactMatchingAutomaton") { + } else if ( algorithm.getValue ( ) == "exactMatchingAutomaton" ) { needPattern = 1; - } else if( algorithm.getValue() == "exactFactorAutomaton") { + } else if ( algorithm.getValue ( ) == "exactFactorAutomaton" ) { needSubject = 1; - } else if( algorithm.getValue() == "exactSubsequenceAutomaton") { + } else if ( algorithm.getValue ( ) == "exactSubsequenceAutomaton" ) { needSubject = 1; - } else if( algorithm.getValue() == "exactNondeterministicSubsequenceAutomaton") { + } else if ( algorithm.getValue ( ) == "exactNondeterministicSubsequenceAutomaton" ) { needSubject = 1; - } else if( algorithm.getValue() == "exactMultiNondeterministicSubsequenceAutomaton") { + } else if ( algorithm.getValue ( ) == "exactMultiNondeterministicSubsequenceAutomaton" ) { needSubject = 2; - } else if( algorithm.getValue() == "borderArray") { + } else if ( algorithm.getValue ( ) == "borderArray" ) { needSubject = 1; } else { } - std::chrono::measurements::start("Overal", std::chrono::measurements::Type::OVERALL); - std::chrono::measurements::start("Input read", std::chrono::measurements::Type::AUXILARY); - - std::deque<std::deque<sax::Token>> subjectTokens; - if(subject.isSet()) { - for(const std::string& fileName : subject.getValue()) { - std::deque<sax::Token> tmp; - if(fileName == "-") { - sax::SaxParseInterface::parseStdin(tmp); - } else { - sax::SaxParseInterface::parseFile(fileName, tmp); - } - subjectTokens.emplace_back(std::move(tmp)); + std::chrono::measurements::start ( "Overal", std::chrono::measurements::Type::OVERALL ); + std::chrono::measurements::start ( "Input read", std::chrono::measurements::Type::AUXILARY ); + + std::deque < std::deque < sax::Token > > subjectTokens; + + if ( subject.isSet ( ) ) { + for ( const std::string & fileName : subject.getValue ( ) ) { + std::deque < sax::Token > tmp; + + if ( fileName == "-" ) + sax::SaxParseInterface::parseStdin ( tmp ); + else + sax::SaxParseInterface::parseFile ( fileName, tmp ); + + subjectTokens.emplace_back ( std::move ( tmp ) ); } - } else if(needSubject) { - std::deque<sax::Token> tmp; - sax::SaxParseInterface::parseStdin(tmp); - subjectTokens.emplace_back(std::move(tmp)); + } else if ( needSubject ) { + std::deque < sax::Token > tmp; + sax::SaxParseInterface::parseStdin ( tmp ); + subjectTokens.emplace_back ( std::move ( tmp ) ); } - std::deque<std::deque<sax::Token>> patternTokens; - if(pattern.isSet()) { - for(const std::string& fileName : pattern.getValue()) { - std::deque<sax::Token> tmp; - if(fileName == "-") { - sax::SaxParseInterface::parseStdin(tmp); - } else { - sax::SaxParseInterface::parseFile(fileName, tmp); - } - patternTokens.emplace_back(std::move(tmp)); + std::deque < std::deque < sax::Token > > patternTokens; + + if ( pattern.isSet ( ) ) { + for ( const std::string & fileName : pattern.getValue ( ) ) { + std::deque < sax::Token > tmp; + + if ( fileName == "-" ) + sax::SaxParseInterface::parseStdin ( tmp ); + else + sax::SaxParseInterface::parseFile ( fileName, tmp ); + + patternTokens.emplace_back ( std::move ( tmp ) ); } - } else if(needPattern) { - std::deque<sax::Token> tmp; - sax::SaxParseInterface::parseStdin(tmp); - patternTokens.emplace_back(std::move(tmp)); + } else if ( needPattern ) { + std::deque < sax::Token > tmp; + sax::SaxParseInterface::parseStdin ( tmp ); + patternTokens.emplace_back ( std::move ( tmp ) ); } - if( algorithm.getValue() == "exactFactorMatch") { - string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens.front()); - string::String pattern = alib::XmlDataFactory::fromTokens<string::String>(patternTokens.front()); + if ( algorithm.getValue ( ) == "exactFactorMatch" ) { + string::String subject = alib::XmlDataFactory::fromTokens < string::String > ( subjectTokens.front ( ) ); + string::String pattern = alib::XmlDataFactory::fromTokens < string::String > ( patternTokens.front ( ) ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); - std::set<unsigned> res = stringology::exact::ExactFactorMatch::match(subject, pattern); + std::set < unsigned > res = stringology::exact::ExactFactorMatch::match ( subject, pattern ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStdout(res); - } else if( algorithm.getValue() == "boyerMooreHorspool") { - string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens.front()); - string::String pattern = alib::XmlDataFactory::fromTokens<string::String>(patternTokens.front()); + alib::XmlDataFactory::toStdout ( res ); + } else if ( algorithm.getValue ( ) == "boyerMooreHorspool" ) { + string::String subject = alib::XmlDataFactory::fromTokens < string::String > ( subjectTokens.front ( ) ); + string::String pattern = alib::XmlDataFactory::fromTokens < string::String > ( patternTokens.front ( ) ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); - std::set<unsigned> res = stringology::exact::BoyerMooreHorspool::match(subject, pattern); + std::set < unsigned > res = stringology::exact::BoyerMooreHorspool::match ( subject, pattern ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStdout(res); - } else if( algorithm.getValue() == "exactMatchingAutomaton") { - string::String pattern = alib::XmlDataFactory::fromTokens<string::String>(patternTokens.front()); + alib::XmlDataFactory::toStdout ( res ); + } else if ( algorithm.getValue ( ) == "exactMatchingAutomaton" ) { + string::String pattern = alib::XmlDataFactory::fromTokens < string::String > ( patternTokens.front ( ) ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); - automaton::Automaton automaton = stringology::exact::ExactMatchingAutomaton::construct(pattern); + automaton::Automaton automaton = stringology::exact::ExactMatchingAutomaton::construct ( pattern ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStdout(automaton); - } else if( algorithm.getValue() == "exactFactorAutomaton") { - string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens.front()); + alib::XmlDataFactory::toStdout ( automaton ); + } else if ( algorithm.getValue ( ) == "exactFactorAutomaton" ) { + string::String subject = alib::XmlDataFactory::fromTokens < string::String > ( subjectTokens.front ( ) ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); - automaton::Automaton automaton = stringology::exact::ExactFactorAutomaton::construct(subject); + automaton::Automaton automaton = stringology::exact::ExactFactorAutomaton::construct ( subject ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStdout(automaton); - } else if( algorithm.getValue() == "exactSubsequenceAutomaton") { - string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens.front()); + alib::XmlDataFactory::toStdout ( automaton ); + } else if ( algorithm.getValue ( ) == "exactSubsequenceAutomaton" ) { + string::String subject = alib::XmlDataFactory::fromTokens < string::String > ( subjectTokens.front ( ) ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); - automaton::Automaton automaton = stringology::exact::ExactSubsequenceAutomaton::construct(subject); + automaton::Automaton automaton = stringology::exact::ExactSubsequenceAutomaton::construct ( subject ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStdout(automaton); - } else if( algorithm.getValue() == "exactNondeterministicSubsequenceAutomaton") { - string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens.front()); + alib::XmlDataFactory::toStdout ( automaton ); + } else if ( algorithm.getValue ( ) == "exactNondeterministicSubsequenceAutomaton" ) { + string::String subject = alib::XmlDataFactory::fromTokens < string::String > ( subjectTokens.front ( ) ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); - automaton::Automaton automaton = stringology::exact::ExactNondeterministicSubsequenceAutomaton::construct(subject); + automaton::Automaton automaton = stringology::exact::ExactNondeterministicSubsequenceAutomaton::construct ( subject ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStdout(automaton); - } else if( algorithm.getValue() == "exactMultiNondeterministicSubsequenceAutomaton") { - std::set<string::String> subjects; - for(std::deque<sax::Token>& tokens : subjectTokens) { - subjects.insert(alib::XmlDataFactory::fromTokens<string::String>(tokens)); - } + alib::XmlDataFactory::toStdout ( automaton ); + } else if ( algorithm.getValue ( ) == "exactMultiNondeterministicSubsequenceAutomaton" ) { + std::set < string::String > subjects; + + for ( std::deque < sax::Token > & tokens : subjectTokens ) + subjects.insert ( alib::XmlDataFactory::fromTokens < string::String > ( tokens ) ); + + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); + + automaton::Automaton automaton = stringology::exact::ExactMultiNondeterministicSubsequenceAutomaton::construct ( subjects ); + + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); + + alib::XmlDataFactory::toStdout ( automaton ); + } else if ( algorithm.getValue ( ) == "borderArray" ) { + string::String subject = alib::XmlDataFactory::fromTokens < string::String > ( subjectTokens.front ( ) ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); - automaton::Automaton automaton = stringology::exact::ExactMultiNondeterministicSubsequenceAutomaton::construct(subjects); + std::vector < unsigned > borderArray = stringology::exact::BorderArray::construct ( subject ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStdout(automaton); - } else if( algorithm.getValue() == "borderArray") { - string::String subject = alib::XmlDataFactory::fromTokens<string::String>(subjectTokens.front()); + alib::XmlDataFactory::toStdout ( borderArray ); + } else if ( algorithm.getValue ( ) == "suffixTrie" ) { + string::String subject = alib::XmlDataFactory::fromTokens < string::String > ( subjectTokens.front ( ) ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Algorithm", std::chrono::measurements::Type::MAIN); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Algorithm", std::chrono::measurements::Type::MAIN ); - std::vector<unsigned> borderArray = stringology::exact::BorderArray::construct(subject); + indexes::SuffixTrie suffixTrie = stringology::indexing::SuffixTrie::construct ( subject ); - std::chrono::measurements::end(); - std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY); + std::chrono::measurements::end ( ); + std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY ); - alib::XmlDataFactory::toStdout(borderArray); + alib::XmlDataFactory::toStdout ( suffixTrie ); } else { - throw exception::AlibException( "Invalid algorithm" ); + throw exception::AlibException ( "Invalid algorithm" ); } - std::chrono::measurements::end(); - std::chrono::measurements::end(); + std::chrono::measurements::end ( ); + std::chrono::measurements::end ( ); - if(measure.getValue()) std::clog << std::chrono::measurements::results() << std::endl; + if ( measure.getValue ( ) ) std::clog << std::chrono::measurements::results ( ) << std::endl; return 0; - } catch( const exception::AlibException & exception ) { - alib::XmlDataFactory::toStdout( exception ); + } catch ( const exception::AlibException & exception ) { + alib::XmlDataFactory::toStdout ( exception ); return 1; - } catch(const TCLAP::ArgException& exception) { - std::cout << exception.error() << std::endl; + } catch ( const TCLAP::ArgException & exception ) { + std::cout << exception.error ( ) << std::endl; return 2; - } catch (const std::exception& exception) { - std::cerr << "Exception caught: " << exception.what() << std::endl; + } catch ( const std::exception & exception ) { + std::cerr << "Exception caught: " << exception.what ( ) << std::endl; return 3; - } catch(...) { + } catch ( ... ) { std::cerr << "Unknown exception caught." << std::endl; return 127; } -- GitLab