vadimk772336

то же самое но с принтами

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