vadimk772336

3 (принты коммент)

Mar 18th, 2022
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.53 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. using namespace std;
  5.  
  6. struct vertex
  7. {
  8. bool is_terminal;
  9. int next[26];
  10. int go[26];
  11. int parent;
  12. char parent_char;
  13. int link;
  14. int depth;
  15. int start;
  16. };
  17.  
  18. void clean_trie(vertex* trie, int size)
  19. {
  20. for (int i = 0; i < size; ++i)
  21. {
  22. trie[i].is_terminal = false;
  23. trie[i].parent = -1;
  24. trie[i].link = -1;
  25. trie[i].depth = 0;
  26. for (int j = 0; j < 26; ++j)
  27. {
  28. trie[i].next[j] = -1;
  29. trie[i].go[j] = -1;
  30. }
  31. }
  32. }
  33.  
  34. void add_string(string s, int s_len, vertex* trie, int& size, int start)
  35. {
  36.  
  37. // cout << "add: " << s << endl;
  38. int v = 0;
  39. int c_idx;
  40. vertex buff;
  41. char c;
  42.  
  43. for (int i = 0; i < s_len; ++i)
  44. {
  45. c = s[i];
  46. c_idx = static_cast<int>(c) - 97;
  47.  
  48. if (trie[v].next[c_idx] == -1)
  49. {
  50. trie[size].link = -1;
  51. trie[size].parent = v;
  52. trie[size].parent_char = c;
  53. trie[v].next[c_idx] = size++;
  54. }
  55.  
  56. v = trie[v].next[c_idx];
  57. }
  58. trie[v].is_terminal = true;
  59. trie[v].depth = s_len;
  60. trie[v].start = start;
  61. }
  62.  
  63. int get_link(int v, char c, vertex* trie);
  64.  
  65. int get_suff_link(int v, vertex* trie)
  66. {
  67. if (trie[v].link == -1)
  68. {
  69. if (v == 0 || trie[v].parent == 0)
  70. trie[v].link = 0;
  71. else
  72. trie[v].link = get_link(get_suff_link(trie[v].parent, trie), trie[v].parent_char, trie);
  73. }
  74. return trie[v].link;
  75. }
  76.  
  77. int get_link(int v, char c, vertex* trie)
  78. {
  79.  
  80. int c_idx = static_cast<int>(c) - 97;
  81.  
  82. if (trie[v].go[c_idx] == -1)
  83. {
  84. if (trie[v].next[c_idx] != -1)
  85. trie[v].go[c_idx] = trie[v].next[c_idx];
  86.  
  87. else if (v == 0)
  88. trie[v].go[c_idx] = 0;
  89.  
  90. else
  91. trie[v].go[c_idx] = get_link(get_suff_link(v, trie), c, trie);
  92. }
  93.  
  94. return trie[v].go[c_idx];
  95. }
  96.  
  97. void fill_trie(int p_len, string P, vertex* trie, int& trie_size, int& count)
  98. {
  99.  
  100. clean_trie(trie, 26 * p_len);
  101.  
  102. int i = 0;
  103. int start = 0;
  104. string mask;
  105. int len_mask;
  106. while (i < p_len)
  107. {
  108. if (P[i] == '?')
  109. {
  110. if (i - start > 0)
  111. {
  112. len_mask = i - start;
  113. mask = P.substr(start, len_mask);
  114. add_string(mask, len_mask, trie, trie_size, start);
  115. count++;
  116. }
  117.  
  118. start = i + 1;
  119. }
  120.  
  121. else if (i == p_len - 1)
  122. {
  123. len_mask = i - start + 1;
  124. mask = P.substr(start, len_mask);
  125. add_string(mask, len_mask, trie, trie_size, start);
  126. }
  127.  
  128. i++;
  129. }
  130. }
  131.  
  132. void display(vertex* trie, int size, bool display_links)
  133. {
  134. for (int i = 0; i < size; ++i)
  135. {
  136. bool flag = true;
  137. for (int j = 0; j < 26; ++j)
  138. {
  139. if (trie[i].next[j] >= 0)
  140. {
  141. if (flag)
  142. {
  143. if (trie[i].is_terminal)
  144. cout << "vertex " << i << ": (is_terminal) ";
  145. else
  146. cout << "vertex " << i << ": ";
  147. flag = false;
  148. }
  149. cout << char(j + 97) << "->" << trie[i].next[j] << " ";
  150. }
  151. }
  152. if (not flag)
  153. cout << endl;
  154. if (flag && trie[i].is_terminal)
  155. cout << "vertex " << i << ": (is_terminal);" << endl;
  156. }
  157.  
  158. if (display_links)
  159. {
  160. cout << "\n Ссылки:" << endl;
  161. for (int v = 0; v < size; ++v)
  162. {
  163. cout << "vertex: " << v << " ";
  164. cout << "suff: " << get_suff_link(v, trie) << "; ";
  165. cout << "get_link: ";
  166. for (int j = 0; j < 26; ++j)
  167. {
  168. int z = get_link(v, char(j + 97), trie);
  169. if (z > 0)
  170. cout << "(" << char(j + 97) << "," << z << ") ";
  171. }
  172. cout << endl;
  173. }
  174. }
  175. }
  176.  
  177. void search_pattern(int t_len, vertex* trie, string T, int& count)
  178. {
  179.  
  180. char c;
  181. int v = 0;
  182. int u;
  183. int c_idx;
  184. int start = 0;
  185.  
  186. vector<int> C(t_len, 0);
  187. int count_pos = 0;
  188.  
  189. for (int i = 0; i < t_len; ++i)
  190. {
  191. c = T[i];
  192. c_idx = static_cast<int>(c) - 97;
  193.  
  194. //cout << "\n Текущий символ: " << c << ", текущая вершина: " << v << endl;
  195.  
  196. //Если нет пути
  197. if (trie[v].next[c_idx] == -1)
  198. {
  199. //cout << "Нет пути - прыгаем по суфф ссылкам из вершины " << v << endl;
  200. //то прыгаем по суфф сылкам назад пока не найдем путь
  201. while (v > 0 && trie[v].next[c_idx] == -1)
  202. {
  203. v = get_suff_link(v, trie);
  204. //cout << "прыгнул в " << v << "; ";
  205. }
  206. //cout << endl;
  207.  
  208. if (trie[v].next[c_idx] != -1)
  209. {
  210. //cout << "Нашли путь, переходим в вершину " << trie[v].next[c_idx] << endl;
  211. v = trie[v].next[c_idx];
  212. }
  213. else
  214. {
  215. //cout << "Путь не найден, сидим в корне, vertex: " << v << endl;
  216. }
  217. }
  218. else
  219. {
  220. //cout << "Путь есть, переходим по ребру в вершину " << trie[v].next[c_idx] << endl;
  221. v = trie[v].next[c_idx];
  222. }
  223.  
  224. //если терминальная принтим и потом бежим по суфф ссылкам до корня в поисках других
  225. //терминальных
  226. if (trie[v].is_terminal)
  227. {
  228. //cout << "Вершина " << v << " оказалась терминальной " << endl;
  229. u = v;
  230. //cout << "Начинаю прыгать по суфф ссылкам: " << endl;
  231. while (u > 0)
  232. {
  233. if (trie[u].is_terminal)
  234. {
  235. //cout << u << "- терминальная - принтим: ";
  236. //cout << "(" << i - trie[u].depth + 1 << "," << i << ")" << endl;
  237. int idx = i - trie[u].depth + 1 - trie[u].start;
  238. if (++C[idx] == count)
  239. count_pos++;
  240. }
  241. u = get_suff_link(u, trie);
  242. //cout << "Прыгнул в " << u << endl;
  243. }
  244. }
  245.  
  246. //else
  247. //cout << "Не терминальная, ждём некст символ " << endl;
  248. //если нет то просто ожидаем некст символ
  249. }
  250.  
  251.  
  252. cout << count_pos << endl;
  253. for (int i =0; i < t_len; ++i)
  254. if (C[i] == count)
  255. cout << i << " ";
  256.  
  257.  
  258. }
  259.  
  260.  
  261. int main()
  262. {
  263.  
  264. string P, T;
  265. cin >> P >> T;
  266. // P = "he?she?his?hers";
  267. //P = "he?she";
  268. // P = "abcd";
  269. //T = "heashe";
  270.  
  271. //P = "ab?";
  272. //T = "ababcabc";
  273.  
  274.  
  275. int p_len = P.length();
  276. int t_len = T.length();
  277.  
  278. int trie_size = 1;
  279. int max_size = 26 * p_len;
  280. vertex trie[max_size];
  281. int count = 0;
  282. fill_trie(p_len, P, trie, trie_size, count);
  283.  
  284. // display(trie,max_size, false);
  285.  
  286. search_pattern(t_len, trie, T, count);
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293. return 0;
  294. }
  295.  
Advertisement
Add Comment
Please, Sign In to add comment