vadimk772336

чуть упроситл (чистый бзе файла)

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