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