Guest User

Untitled

a guest
Nov 19th, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.42 KB | None | 0 0
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <vector>
  5. #include <string>
  6. #include <map>
  7.  
  8. using namespace std;
  9.  
  10. struct Node;
  11.  
  12. int* last_symbol_index;
  13. Node* root;
  14. string line;
  15.  
  16. int global_node_index = 0;
  17.  
  18. struct Node
  19. {
  20. Node* suffix_link;
  21. Node* parent;
  22. int start;
  23. int* end;
  24.  
  25. int node_index;
  26.  
  27. map<char, Node*> children;
  28.  
  29. Node(): suffix_link(NULL), parent(NULL), start(0), end(last_symbol_index), node_index(global_node_index++) {}
  30. Node(Node* parent_, int start_)
  31. : suffix_link(NULL), parent(parent_), start(start_), end(last_symbol_index), node_index(global_node_index++) {}
  32. ~Node() { if(end != last_symbol_index) delete end; }
  33. int size() { return *end - start; }
  34. };
  35.  
  36. struct State
  37. {
  38. Node* closest_node;
  39. int offset;
  40. State(Node* closest_node_, int offset_): closest_node(closest_node_), offset(offset_) {}
  41. };
  42.  
  43. bool try_move_by_edge(State& state, int start, int end)
  44. {
  45. while(start < end)
  46. {
  47. if(state.offset == state.closest_node->size()) //offset covers edge
  48. {
  49. if(state.closest_node->children.count(line[start]) == 0) //no edge with current_symbol
  50. return false;
  51. state.closest_node = state.closest_node->children[line[start]];
  52. state.offset = 0;
  53. }
  54. else
  55. {
  56. int edge_length = state.closest_node->size();
  57. if(line[state.closest_node->start + state.offset] != line[start]) //next symbol of edge != current_symbol
  58. return false;
  59.  
  60. if(end - start < edge_length - state.offset) //current_symbol is of the edge
  61. {
  62. state.offset += end - start;
  63. return true;
  64. }
  65. start += edge_length - state.offset;
  66. state.offset = edge_length;
  67. }
  68. }
  69. return true;
  70. }
  71.  
  72. Node* split_current_edge(State& state)
  73. {
  74. if(state.offset == state.closest_node->size())
  75. return state.closest_node;
  76. if(state.offset == 0)
  77. return state.closest_node->parent;
  78.  
  79. Node* split_node = new Node(state.closest_node->parent, state.closest_node->start);
  80. split_node->end = new int(state.closest_node->start + state.offset);
  81.  
  82. state.closest_node->parent->children[line[state.closest_node->start]] = split_node;
  83. split_node->children[line[state.closest_node->start + state.offset]] = state.closest_node;
  84. state.closest_node->parent = split_node;
  85. state.closest_node->start += state.offset;
  86.  
  87. return split_node;
  88. }
  89.  
  90. void move_by_suffix_link(State& state)
  91. {
  92. if(state.closest_node->suffix_link != NULL)
  93. {
  94. state.closest_node = state.closest_node->suffix_link;
  95. }
  96. else
  97. {
  98. Node* current = state.closest_node;
  99.  
  100. state.closest_node = current->parent;
  101. move_by_suffix_link(state);
  102. state.offset = state.closest_node->size();
  103. try_move_by_edge(state, current->start + (current->parent == root), *current->end);
  104.  
  105. state.closest_node = current->suffix_link = split_current_edge(state);
  106. }
  107. }
  108.  
  109. void output(Node* n, ofstream& fo, Node* exception)
  110. {
  111. for(auto child = n->children.begin(); child != n->children.end(); ++child)
  112. {
  113. if(child->second == exception)
  114. continue;
  115. fo << n->node_index << "\t->\t" << child->second->node_index
  116. << " [label=\""
  117. << line.substr(child->second->start, *child->second->end - child->second->start)
  118. << "\"];\n";
  119. output(child->second, fo, exception);
  120. }
  121. }
  122.  
  123. void exterial_output(Node* n, ofstream& fo, Node* exception)
  124. {
  125. fo << "digraph G {\n";
  126. output(n, fo, exception);
  127. fo << "}\n";
  128. }
  129.  
  130. bool find_word(const string& word)
  131. {
  132. Node* search_node = root;
  133. for(auto word_symbol = word.begin(); word_symbol != word.end();)
  134. {
  135. if(search_node->children.count(*word_symbol) == 0)
  136. return false;
  137. search_node = search_node->children[*word_symbol];
  138. for
  139. (
  140. int edge_it = search_node->start;
  141. edge_it < *search_node->end && word_symbol != word.end();
  142. ++edge_it, ++word_symbol
  143. )
  144. if(line[edge_it] != *word_symbol)
  145. return false;
  146. }
  147. return true;
  148. }
  149.  
  150. int main()
  151. {
  152. ifstream fi("input.txt");
  153. ofstream fo("output.txt");
  154.  
  155. getline(fi, line);
  156. last_symbol_index = new int(line.size());
  157.  
  158. root = new Node();
  159. root->end = new int(0);
  160. root->suffix_link = root;
  161. State start_point(root, 0);
  162.  
  163. for(int current_symbol_index = 0; current_symbol_index < line.size(); ++current_symbol_index)
  164. {
  165. while(!try_move_by_edge(start_point, current_symbol_index, current_symbol_index + 1))
  166. {
  167. Node* middle_node = start_point.closest_node = split_current_edge(start_point);
  168.  
  169. start_point.closest_node->children[line[current_symbol_index]] =
  170. new Node(start_point.closest_node, current_symbol_index);
  171.  
  172. move_by_suffix_link(start_point);
  173. start_point.offset = start_point.closest_node->size();
  174. if(middle_node == root)
  175. break;
  176. }
  177. }
  178. /*
  179. ofstream graph_fo("output_graph.txt");
  180. exterial_output(root, graph_fo, NULL);
  181. graph_fo.close();
  182. */
  183. int number_of_words;
  184. fi >> number_of_words >> ws;
  185. for(int word_index = 0; word_index < number_of_words; ++word_index)
  186. {
  187. string word;
  188. getline(fi, word);
  189. fo << find_word(word) << " ";
  190. }
  191.  
  192. return 0;
  193. }
Add Comment
Please, Sign In to add comment