vadimk772336

файл

Mar 19th, 2022
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.63 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <fstream>
  5. using namespace std;
  6.  
  7.  
  8. struct vertex
  9. {
  10. bool is_terminal;
  11. int next[26];
  12. int go[26];
  13. int parent;
  14. char parent_char;
  15. int link;
  16. int depth;
  17. std::vector<int> end;
  18. int len_end;
  19. int short_link;
  20. };
  21.  
  22. void clean_trie(vertex* trie, int size)
  23. {
  24. for (int i = 0; i < size; ++i)
  25. {
  26. trie[i].is_terminal = false;
  27. trie[i].parent = -1;
  28. trie[i].link = -1;
  29. trie[i].short_link = -1;
  30. trie[i].depth = 0;
  31. trie[i].len_end = 0;
  32. for (int j = 0; j < 26; ++j)
  33. {
  34. trie[i].next[j] = -1;
  35. trie[i].go[j] = -1;
  36. }
  37. }
  38. }
  39.  
  40. void add_string(std::string s, int s_len, vertex* trie, int& size, int end)
  41. {
  42.  
  43. int v = 0;
  44. int c_idx;
  45. vertex buff;
  46. char c;
  47.  
  48. for (int i = 0; i < s_len; ++i)
  49. {
  50. c = s[i];
  51. c_idx = static_cast<int>(c) - 97;
  52.  
  53. if (trie[v].next[c_idx] == -1)
  54. {
  55. trie[size].link = -1;
  56. trie[size].parent = v;
  57. trie[size].parent_char = c;
  58. trie[v].next[c_idx] = size++;
  59. }
  60.  
  61. v = trie[v].next[c_idx];
  62. }
  63. trie[v].is_terminal = true;
  64. trie[v].depth = s_len;
  65. trie[v].end.push_back(end);
  66. trie[v].len_end++;
  67. }
  68.  
  69. int get_link(int v, char c, vertex* trie);
  70.  
  71. int get_suff_link(int v, vertex* trie)
  72. {
  73. if (trie[v].link == -1)
  74. {
  75. if (v == 0 || trie[v].parent == 0)
  76. trie[v].link = 0;
  77. else
  78. trie[v].link = get_link(get_suff_link(trie[v].parent, trie), trie[v].parent_char, trie);
  79. }
  80. return trie[v].link;
  81. }
  82.  
  83. int get_link(int v, char c, vertex* trie)
  84. {
  85.  
  86. int c_idx = static_cast<int>(c) - 97;
  87.  
  88. if (trie[v].go[c_idx] == -1)
  89. {
  90. if (trie[v].next[c_idx] != -1)
  91. trie[v].go[c_idx] = trie[v].next[c_idx];
  92.  
  93. else if (v == 0)
  94. trie[v].go[c_idx] = 0;
  95.  
  96. else
  97. trie[v].go[c_idx] = get_link(get_suff_link(v, trie), c, trie);
  98. }
  99.  
  100. return trie[v].go[c_idx];
  101. }
  102.  
  103. int get_short_link(int v, vertex* trie)
  104. {
  105. if (trie[v].short_link == -1)
  106. {
  107. int u = get_suff_link(v, trie);
  108. if (trie[u].is_terminal || u == 0)
  109. trie[v].short_link = u;
  110. else
  111. trie[v].short_link = get_short_link(u, trie);
  112. }
  113.  
  114. return trie[v].short_link;
  115. }
  116.  
  117. void fill_trie(int p_len, std::string P, vertex* trie, int& trie_size, int& count)
  118. {
  119.  
  120. clean_trie(trie, 26 * p_len);
  121.  
  122. int i = 0;
  123. int start = 0;
  124. std::string mask;
  125. int len_mask;
  126. while (i < p_len)
  127. {
  128. if (P[i] == '?')
  129. {
  130. if (i - start > 0)
  131. {
  132. len_mask = i - start;
  133. mask = P.substr(start, len_mask);
  134. add_string(mask, len_mask, trie, trie_size, i - 1);
  135. count++;
  136. }
  137.  
  138. start = i + 1;
  139. }
  140.  
  141. else if (i == p_len - 1)
  142. {
  143. len_mask = i - start + 1;
  144. mask = P.substr(start, len_mask);
  145. add_string(mask, len_mask, trie, trie_size, i);
  146. count++;
  147. }
  148. i++;
  149. }
  150. }
  151.  
  152. ofstream out("results.txt");
  153. void search_pattern(int t_len, vertex* trie, std::string T, int& count, int p_len)
  154. {
  155.  
  156.  
  157. if (count == 0)
  158. {
  159. count = t_len - p_len + 1;
  160. out << count << " ";
  161. for (int i = 0; i < count; ++i)
  162. out << i << " ";
  163. }
  164.  
  165. else
  166. {
  167. char c;
  168. int v = 0;
  169. int u;
  170. int c_idx;
  171. int start = 0;
  172.  
  173. int C[t_len];
  174. int count_pos = 0;
  175.  
  176. for (int i = 0; i < t_len; ++i)
  177. C[i] = 0;
  178.  
  179. for (int i = 0; i < t_len; ++i)
  180. {
  181. c = T[i];
  182. c_idx = static_cast<int>(c) - 97;
  183.  
  184. if (trie[v].next[c_idx] == -1)
  185. {
  186. while (v > 0 && trie[v].next[c_idx] == -1)
  187. {
  188. v = get_suff_link(v, trie);
  189. }
  190.  
  191. if (trie[v].next[c_idx] != -1)
  192. {
  193. v = trie[v].next[c_idx];
  194. }
  195. }
  196.  
  197. else
  198. v = trie[v].next[c_idx];
  199.  
  200.  
  201. u = v;
  202. while (u > 0)
  203. {
  204. if (trie[u].is_terminal)
  205. {
  206. for (int k = 0; k < trie[u].len_end; ++k)
  207. {
  208. int idx = i - trie[u].end[k];
  209. if (idx >= 0 && idx < t_len && (p_len + idx - 1 < t_len))
  210. {
  211. C[idx]++;
  212. if (C[idx] == count)
  213. count_pos++;
  214. }
  215. }
  216. }
  217. u = get_short_link(u, trie);
  218. }
  219. }
  220.  
  221. out << count_pos << " ";
  222. for (int i = 0; i < t_len; ++i)
  223. if (C[i] == count)
  224. out << i << " ";
  225. }
  226. }
  227.  
  228. int main()
  229. {
  230.  
  231. int count_tests;
  232. ifstream ifs("tests.txt");
  233. ifs >> count_tests;
  234.  
  235.  
  236. for (int i = 0; i < count_tests; ++i)
  237. {
  238.  
  239. std::string P, T;
  240. ifs >> P >> T;
  241. //std::cin >> P >> T;
  242. int p_len = P.length();
  243. int t_len = T.length();
  244.  
  245.  
  246. int count = 0;
  247. int trie_size = 1;
  248. vertex trie[p_len * 26 + 1];
  249.  
  250. fill_trie(p_len, P, trie, trie_size, count);
  251.  
  252. search_pattern(t_len, trie, T, count, p_len);
  253. out << "\n";
  254. }
  255. return 0;
  256. }
  257.  
Advertisement
Add Comment
Please, Sign In to add comment