--- /dev/null
+#include <iostream>\r
+#include <vector>\r
+#include <string>\r
+\r
+#include "typedef.h"\r
+#include "algorithm.h"\r
+#include "trie.h"\r
+\r
+/**\r
+ * Adds patterns to trie.\r
+ */\r
+void aho::algorithm::add_patterns_to_trie() {\r
+ uint max_size_of_patterns = 0;\r
+\r
+ for(uint i = 0; i < this->patterns.size(); i++) {\r
+ max_size_of_patterns = max_size_of_patterns < this->patterns[i].size() ? this->patterns[i].size() : max_size_of_patterns;\r
+ }\r
+\r
+ for(uint letter_iterator = 0; letter_iterator < max_size_of_patterns; letter_iterator++) {\r
+ for(uint pattern_iterator = 0; pattern_iterator < this->patterns.size(); pattern_iterator++) {\r
+ tstring current_pattern = this->patterns[pattern_iterator];\r
+\r
+ if(letter_iterator < current_pattern.size()) {\r
+ this->trie->add_child(new aho::trie(current_pattern.substr(0, letter_iterator + 1)));\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+void aho::algorithm::set_patterns_in_trie() {\r
+ //Iterate over all patterns\r
+ for(uint i = 0; i < this->patterns.size(); i++) {\r
+ //Return to root node.\r
+ class aho::trie * node = this->trie;\r
+ tstring pattern = this->patterns[i];\r
+\r
+ //Search for pattern in trie\r
+ for(uint j = 0; j < pattern.size(); j++) {\r
+ node = node->get_child(pattern.substr(0, j + 1).c_str());\r
+ }\r
+ //Set found node as pattern\r
+ node->is_pattern(true);\r
+ }\r
+}\r
+\r
+void aho::algorithm::set_suffix_link() {\r
+ for(uint j = 0; j < this->list.size(); j++) {\r
+ class aho::trie * node = this->list[j];\r
+\r
+ for(uint k = 1; k < node->get_value().size(); k++) {\r
+ tstring suffix = (node->get_value().substr(k));\r
+\r
+ class aho::trie * found = NULL;\r
+ if((found = this->trie->get_child(suffix, true)) != NULL) {\r
+ if(node->get_suffix(found->get_value()) == NULL) {\r
+ node->add_suffix(found);\r
+ }\r
+ break;\r
+ }\r
+ \r
+ }\r
+ }\r
+ return;\r
+}\r
+\r
+void aho::algorithm::set_nodes_list() {\r
+ for(uint i = 0; i < this->patterns.size(); i++) {\r
+ for(uint j = 1; j <= this->patterns[i].size(); j++) {\r
+ class aho::trie * node = this->get_node(this->patterns[i].substr(0, j));\r
+ //TODO: Pozbyæ siê powtarzania\r
+ if(!this->is_on_nodes_list(node)) {\r
+ this->list.push_back(node);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * Checks if node exists on node list.\r
+ */\r
+bool aho::algorithm::is_on_nodes_list(class aho::trie * node) {\r
+ for(uint i = 0; i < this->list.size(); i++) {\r
+ if(this->list[i] == node) {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+}\r
+\r
+/**\r
+ * Adds pattern to search in a subject text.\r
+ */\r
+void aho::algorithm::add_search_pattern(tstring pattern) {\r
+ this->patterns.push_back(pattern);\r
+\r
+ for(uint i = 0; i < pattern.size(); i++) {\r
+ if(this->letters.find(pattern[i]) == tstring::npos) {\r
+ this->letters.push_back(pattern[i]);\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ * Create trie.\r
+ */\r
+void aho::algorithm::generate_trie() {\r
+ this->add_patterns_to_trie();\r
+ this->set_patterns_in_trie();\r
+ this->set_nodes_list();\r
+ this->set_suffix_link();\r
+}\r
+\r
+/**\r
+ * Search subject text for patterns.\r
+ */\r
+void aho::algorithm::parse() {\r
+ uint length = this->subject.size();\r
+ class aho::trie * current_node = this->trie;\r
+\r
+ for(uint j = 0; j < length; j++) {\r
+ tstring letter;\r
+ letter = this->subject[j];\r
+\r
+ tstring value(current_node->get_value() + letter);\r
+\r
+ class aho::trie * node = current_node->get_child(value);\r
+ class aho::trie * suffix_node = NULL;\r
+\r
+ if(node == NULL) {\r
+ //value = abc\r
+ //szukaj najd³u¿szego sufixu w node'zie\r
+\r
+ for(uint k = 1; k < value.size(); k++) {\r
+// tstring suffix(current_node->get_value().substr(k));\r
+ if((suffix_node = current_node->get_suffix(value.substr(k))) != NULL) {\r
+ node = suffix_node;\r
+ break;\r
+ }\r
+ else if((suffix_node = current_node->get_suffix(current_node->get_value().substr(k))) != NULL) {\r
+ node = suffix_node;\r
+ j -= k;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if(node) {\r
+ if(this->is_pattern(node)) {\r
+\r
+ this->save_result(node->get_value(), j+2-node->get_value().size());\r
+\r
+/*\r
+W przypadku natrafienia na wêze³\r
+oznaczony jako koniec s³owa, algorytm wypisuje je jako znalezione w tek\9ccie oraz sprawdza, czy czasem w tym\r
+miejscu nie koñczy siê wiêcej wzorców przechodz¹c krawêdziami fail a¿ do korzenia sprawdzaj¹c, czy nie\r
+przechodzi po wierzcho³ku bêd¹cym koñcem wzorca.\r
+*/\r
+ //Sprawd\9f suffixy je\9cli istniej¹\r
+ class aho::trie * other = node->get_suffix();\r
+ while(other != NULL) {\r
+ if(this->is_pattern(other)) {\r
+ this->save_result(other->get_value(), j+2-other->get_value().size());\r
+ }\r
+ if(other->get_child(other->get_value() + this->subject[j+1])) {\r
+ break;\r
+ }\r
+ other = other->get_suffix();\r
+ }\r
+ if(!other) {\r
+ other = this->trie;\r
+ }\r
+ //Zgubi³ w¹tek, bo natrafi³ na literê, która nie jest dzieckiem.\r
+ //Przejecha³ po suffixach...\r
+ //Pozosta³o sprawdziæ, czy na podstawie\r
+ if(!node->get_child(node->get_value() + this->subject[j+1])) {\r
+ node = other;\r
+ }\r
+ }\r
+ current_node = node;\r
+ }\r
+ current_node = node ? node : this->trie;\r
+\r
+ }\r
+ \r
+ return;\r
+}
\ No newline at end of file
--- /dev/null
+#ifndef AHO_ALGORITHM_H\r
+#define AHO_ALGORITHM_H\r
+\r
+#include <iostream>\r
+#include <vector>\r
+#include <string>\r
+\r
+#include "typedef.h"\r
+#include "trie.h"\r
+\r
+/*\r
+At each step, the current node is extended by finding its daughter,\r
+and if that doesn't exist, finding its suffix's daughter, \r
+and if that doesn't work, finding its suffix's suffix's daughter,\r
+finally ending in the root node if nothing's seen before.\r
+*/\r
+namespace aho {\r
+ \r
+// class result {\r
+// private:\r
+// protected:\r
+// public:\r
+// tstring rslt;\r
+// int position;\r
+// };\r
+\r
+class algorithm {\r
+ private:\r
+ protected:\r
+ class aho::trie * trie;\r
+\r
+ std::vector<tstring> patterns;\r
+ tstring subject;\r
+ tstring letters;\r
+\r
+ std::vector<class aho::trie *> list;\r
+\r
+ void add_patterns_to_trie();\r
+\r
+ /**\r
+ * Sets which nodes in trie, are the searched patterns.\r
+ */\r
+ void set_patterns_in_trie();\r
+\r
+ /**\r
+ * Sets node list.\r
+ */\r
+ void set_nodes_list();\r
+\r
+ /**\r
+ * Sets suffix links for each pattern in trie.\r
+ */\r
+ void set_suffix_link();\r
+\r
+ /**\r
+ * Checks if node is a searched pattern.\r
+ */\r
+ virtual bool is_pattern(class aho::trie * node) {\r
+ return node->is_pattern();\r
+ }\r
+\r
+ bool is_on_nodes_list(class aho::trie * node);\r
+ \r
+ /**\r
+ * Gets node by its value\r
+ */\r
+ class aho::trie * get_node(tstring value) {\r
+ return this->trie->get_child(value, true);\r
+ }\r
+\r
+ /**\r
+ * Saves search results\r
+ */\r
+ virtual void save_result(tstring search, uint position) {\r
+ printf("%s: %d\n", search.c_str(), position);\r
+ }\r
+ public:\r
+ /**\r
+ * Algorithm constructor. Initializes variables.\r
+ */\r
+ algorithm() : trie(new aho::trie(TXT(""))) {\r
+ }\r
+\r
+ /**\r
+ * Algorithm destructor.\r
+ */\r
+ ~algorithm() {\r
+ if(this->trie != NULL) {\r
+ delete this->trie;\r
+ }\r
+ }\r
+ void add_search_pattern(tstring pattern);\r
+\r
+ /**\r
+ * Sets subject text in which patterns will be searched.\r
+ */\r
+ void set_search_subject(tstring subject) {\r
+ this->subject = subject;\r
+ }\r
+\r
+ void generate_trie();\r
+ void parse();\r
+ };\r
+};\r
+\r
+#endif
\ No newline at end of file
--- /dev/null
+#include <iostream>\r
+\r
+#include "typedef.h"\r
+#include "algorithm.h"\r
+#include "trie.h"\r
+\r
+int main(int argc, int **argv) {\r
+ class aho::algorithm * algorithm = new aho::algorithm();\r
+\r
+ tfstream file("test.txt");\r
+ uint number_of_words;\r
+ file >> number_of_words;\r
+\r
+ for(uint i = 0; i < number_of_words; i++) {\r
+ tstring word;\r
+ file >> word;\r
+ algorithm->add_search_pattern(word);\r
+ tcout << word;\r
+ }\r
+\r
+// algorithm->add_search_pattern("Drogi");\r
+// algorithm->add_search_pattern("Marszalku");\r
+// algorithm->add_search_pattern("ze");\r
+// algorithm->add_search_pattern("i");\r
+// algorithm->add_search_pattern("Jak");\r
+ tstring subject;\r
+ tstring tmp;\r
+ while(!file.eof()) {\r
+ file >> tmp;\r
+ subject += tmp + " ";\r
+ }\r
+\r
+// algorithm->set_search_subject("Drogi Marszalku, Wysoka Izbo. PKB ro\9cnie. Z drugiej strony, rozszerzenie bazy o nowe rekordy poci¹ga za sob¹ proces wdrozenia i unowocze\9cniania form dzia³alno\9cci wymaga sprecyzowania i unowocze\9cniania nowych propozycji. Ka¿dy ju¿ mówi³em jasne jest wa¿ne zadanie w kszta³towaniu kolejnych kroków w przygotowaniu i realizacji kolejnych kroków w okre\9claniu istniej¹cych kryteriów wymaga sprecyzowania i realizacji odpowiednich warunków administracyjno-finansowych. Jak ju¿ mówi³em jasne jest to, ze rozszerzenie bazy o tym, usprawnienie systemu powszechnego uczestnictwa. Przez ostatnie kilkana\9ccie lat odkryli\9cmy ze rozszerzenie naszej dzia³alno\9cci organizacyjnej rozszerza nam efekt obecnej sytuacji. Z drugiej strony, zakres i bogate do\9cwiadczenia pozwalaj¹ na uwadze, ze wdrozenie nowych, lepszych rozwi¹zañ wymaga niezwyk³ej precyzji w restrukturyzacji przedsiêbiorstwa. Jak ju¿ zapewne zd¹¿y³ zauwa¿yæ i¿ zakres i unowocze\9cniania postaw uczestników wobec zadañ programowych jest to, ze aktualna struktura organizacji koliduje z powodu nowych propozycji. Nasza propozycja. Praktyka dnia codziennego dowodzi, ze konsultacja z dotychczasowymi zasadami kierunków postêpowego wychowania. Reasumuj¹c. nowy model dzia³alno\9cci organizacyjnej ukazuje nam horyzonty kolejnych kroków w kszta³towaniu systemu szkolenia kadr koliduje z powodu obecnej sytuacji. W ten sposób dalszy rozwój ró¿nych form dzia³alno\9cci organizacyjnej jest zauwazenie, ze inwestowanie.");\r
+ algorithm->set_search_subject(subject);\r
+\r
+ algorithm->generate_trie();\r
+ algorithm->parse();\r
+\r
+ delete algorithm;\r
+\r
+ return 0;\r
+}
\ No newline at end of file
--- /dev/null
+#ifndef AHO_TRIE_H\r
+#define AHO_TRIE_H\r
+\r
+#include <vector>\r
+#include <map>\r
+\r
+#include "typedef.h"\r
+\r
+namespace aho {\r
+ class trie {\r
+ public:\r
+ typedef trie _Myt;\r
+ typedef tstring _string;\r
+ private:\r
+ _string value;\r
+ class aho::trie * parent;\r
+\r
+ std::map<_string, class aho::trie *> suffixes;\r
+ std::vector<class aho::trie *> children;\r
+\r
+ bool pattern;\r
+ \r
+ /**\r
+ * Checks if a trie node should be nested in current node.\r
+ * @param node Trie node which will be compared with current node.\r
+ * @return returns true if node should be nested. False otherwise.\r
+ */\r
+ bool should_be_nested(class aho::trie * node) {\r
+ return this->value.size() < node->get_value().size() ? true : false;\r
+ }\r
+ protected:\r
+ public:\r
+ /**\r
+ * Trie class constructor. Initializes variables with default values.\r
+ * @param value text value of trie's node.\r
+ */\r
+ trie(_string _value) : parent(NULL), pattern(false), value(_value) { }\r
+ \r
+ /**\r
+ * Sets value of trie node.\r
+ * @param value Value which will be used to set the trie node value.\r
+ */\r
+ void set_value(_string value) {\r
+ this->value = value;\r
+ }\r
+\r
+ /**\r
+ * Sets parent node of this trie node.\r
+ * @param parent Parent node for current trie node.\r
+ */\r
+ void set_parent(class aho::trie * node) {\r
+ this->parent = node;\r
+ }\r
+ \r
+ /**\r
+ * Adds node to the trie.\r
+ * @param node Trie node which will be added to the current node.\r
+ */\r
+ void add_child(class aho::trie * node) {\r
+ //Je¿eli powinien byæ zagnie¿d¿ony (bo d³u¿szy)\r
+ if(this->should_be_nested(node)) {\r
+ uint length = this->value.size() + 1;\r
+\r
+ //Je¿eli nie znalaz³ wpisu o danym fragmencie nazwy...\r
+ class aho::trie * tmp = this->get_child(node->get_value().substr(0, length));\r
+ if(tmp == NULL) {\r
+ //Je¿eli to jest nadal fragment (nie jest to pe³na nazwa).\r
+ if(length < node->get_value().size()) {\r
+ tmp = new aho::trie(node->get_value().substr(0, length + 1));\r
+ tmp->set_parent(this);\r
+ node->set_parent(tmp);\r
+ tmp->add_child(node);\r
+ this->children.push_back(tmp);\r
+ //this->children[tmp->get_value()] = tmp;\r
+ }\r
+ //WARNING!\r
+ //Je¿eli to ju¿ jest pe³na nazwa...\r
+ else {\r
+ node->set_parent(this);\r
+ this->children.push_back(node);\r
+ //this->children[node->get_value()] = node;\r
+ }\r
+ }\r
+ //Je¿eli znalaz³ wpis o takim fragmencie nazwy, to rekursywnie...\r
+ else {\r
+ if(length < node->get_value().size()) {\r
+ node->set_parent(tmp);\r
+ tmp->add_child(node);\r
+ }\r
+ }\r
+ }\r
+ //TODO: (?)\r
+ //Je¿eli ma nie byæ zagnie¿d¿ony...(Czyli, je¿eli powinien byæ dok³adnie na tym poziomie...)\r
+ else {\r
+ if(this->get_value() == node->get_value()) {\r
+ delete node;\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sets suffix link of the current node with a given node.\r
+ * @param node Pointer to node, which will be linked as a suffix.\r
+ */\r
+ void add_suffix(class aho::trie * node) {\r
+ this->suffixes[node->get_value()] = node;\r
+ }\r
+ \r
+ /**\r
+ * Gets value of current node.\r
+ * @return Returns node value.\r
+ */\r
+ _string get_value() {\r
+ return this->value;\r
+ }\r
+ \r
+ /**\r
+ * Gets specific child node of the current one.\r
+ * @param value Specifies node which has argument's value set in value.\r
+ * @param recursive If true, longest passing node is searched recursively. Otherwise child node of current one with exactly same value is searched.\r
+ * @return Returns pointer to node, if the node has been found. NULL otherwise.\r
+ */\r
+ class aho::trie * get_child(_string value, bool recursive = false) {\r
+ for(uint i = 0; i < this->children.size(); i++) {\r
+ //Je¿eli znalaz³, to zwróæ\r
+ if(this->children[i]->get_value() == value) {\r
+ return this->children[i];\r
+ }\r
+ else if(recursive && (this->children[i]->get_value().compare(value.substr(0, this->children[i]->get_value().size())) == 0)) {\r
+ return this->children[i]->get_child(value, recursive);\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+ }\r
+ \r
+ /**\r
+ * Gets node's suffix\r
+ * @param value text value of suffix.\r
+ * @return Returns pointer to suffix node, if the node has been found. NULL otherwise.\r
+ */\r
+ class aho::trie * get_suffix(_string value = TXT("")) {\r
+ return this->suffixes[value];\r
+ }\r
+\r
+ /**\r
+ * Gets parent node of the current trie node.\r
+ */\r
+ class aho::trie * get_parent(){\r
+ return this->parent;\r
+ }\r
+ \r
+ /**\r
+ * Checks if current node is one of patterns to search.\r
+ * @return Returns true, if node is one of patterns. False otherwise.\r
+ */\r
+ bool is_pattern() {\r
+ return this->pattern;\r
+ }\r
+ \r
+ /**\r
+ * Sets node to be a pattern to search.\r
+ * @param pattern Specifies if node is a pattern.\r
+ */\r
+ void is_pattern(bool pattern) {\r
+ this->pattern = pattern;\r
+ }\r
+ };\r
+};\r
+\r
+#endif
\ No newline at end of file
--- /dev/null
+/***************************************************************************\r
+ * Copyright (C) 2008 by Rafa³ D³ugo³êcki *\r
+ * dlugolecki.rafal@gmail.com *\r
+ * quayle@wp.pl *\r
+ * *\r
+ * This program is free software; you can redistribute it and/or modify *\r
+ * it under the terms of the GNU General Public License as published by *\r
+ * the Free Software Foundation; either version 2 of the License, or *\r
+ * (at your option) any later version. *\r
+ * *\r
+ * This program is distributed in the hope that it will be useful, *\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
+ * GNU General Public License for more details. *\r
+ * *\r
+ * You should have received a copy of the GNU General Public License *\r
+ * along with this program; if not, write to the *\r
+ * Free Software Foundation, Inc., *\r
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
+ ***************************************************************************/\r
+\r
+/* Rafa³ D³ugo³êcki */\r
+\r
+//\r
+// File: typedef.h\r
+// Author: rafal\r
+//\r
+// Created on 29 lipiec 2008, 22:37\r
+//\r
+\r
+#ifndef _TYPEDEF_H\r
+#define _TYPEDEF_H\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+#include <ostream>\r
+#include <istream>\r
+#include <sstream>\r
+#include <string>\r
+#include <cctype>//for isalnum and others...\r
+#include <cwctype>//for wide version of above\r
+#include <typeinfo>\r
+\r
+#include "config.h"\r
+/*\r
+ * Typedefs\r
+ */\r
+typedef unsigned int uint;\r
+\r
+#ifdef USE_WCHAR\r
+ typedef wchar_t tchar;\r
+//these are not types but variables\r
+# define tcout std::wcout\r
+# define tcin std::wcin\r
+# define tcerr std::wcerr\r
+# define TXT(x) L##x\r
+# define TCHAR_TYPE TXT("wchar_t")\r
+\r
+//these are functions\r
+ \r
+# define tisalnum(c) std::iswalnum(c)\r
+# define tisalpha(c) std::iswalpha(c)\r
+# define tiscntrl(c) std::iswcntrl(c)\r
+# define tisdigit(c) std::iswdigit(c)\r
+# define tisgraph(c) std::iswgraph(c)\r
+# define tislower(c) std::iswlower(c)\r
+# define tisprint(c) std::iswprint(c)\r
+# define tispunct(c) std::iswpunct(c)\r
+# define tisspace(c) std::iswspace(c)\r
+# define tisupper(c) std::iswupper(c)\r
+# define tisxdigit(c) std::iswxdigit(c)\r
+ \r
+#else\r
+ typedef char tchar;\r
+//these are not types but variables\r
+# define tcout std::cout\r
+# define tcin std::cin\r
+# define tcerr std::cerr\r
+# define TXT(x) x\r
+# define TCHAR_TYPE TXT("char")\r
+//these are functions\r
+ \r
+# define tisalnum(c) std::isalnum(c)\r
+# define tisalpha(c) std::isalpha(c)\r
+# define tiscntrl(c) std::iscntrl(c)\r
+# define tisdigit(c) std::isdigit(c)\r
+# define tisgraph(c) std::isgraph(c)\r
+# define tislower(c) std::islower(c)\r
+# define tisprint(c) std::isprint(c)\r
+# define tispunct(c) std::ispunct(c)\r
+# define tisspace(c) std::isspace(c)\r
+# define tisupper(c) std::isupper(c)\r
+# define tisxdigit(c) std::isxdigit(c)\r
+ \r
+#endif\r
+\r
+#ifdef USE_ICU\r
+ typedef UChar tchar;\r
+//these are not types but variables\r
+# define tcout std::cout\r
+# define tcin std::cin\r
+# define tcerr std::cerr\r
+# define TXT(x) x\r
+# define TCHAR_TYPE TXT("wchar_t or uint16_t")\r
+#endif\r
+\r
+typedef std::basic_string <tchar> tstring;\r
+\r
+typedef std::basic_istream<tchar> tistream;\r
+typedef std::basic_ostream<tchar> tostream;\r
+\r
+typedef std::basic_fstream<tchar> tfstream;\r
+typedef std::basic_ifstream<tchar> tifstream;\r
+typedef std::basic_ofstream<tchar> tofstream;\r
+\r
+typedef std::basic_stringstream<tchar> tstringstream;\r
+typedef std::basic_istringstream<tchar> tistringstream;\r
+typedef std::basic_ostringstream<tchar> tostringstream;\r
+\r
+typedef std::basic_stringbuf<tchar> tstringbuf;\r
+typedef std::basic_filebuf<tchar> tfilebuf;\r
+\r
+#ifdef USE_BOOST\r
+# include <boost/algorithm/string.hpp>\r
+#endif\r
+\r
+\r
+\r
+#endif\r