vadimk772336

без disolay

Mar 18th, 2022 (edited)
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.09 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3.  
  4. struct vertex
  5. {
  6.     bool is_terminal;
  7.     int next[26];
  8.     int go[26];
  9.     int parent;
  10.     char parent_char;
  11.     int link;
  12.     int depth;
  13.     int start;
  14. };
  15.  
  16. void clean_trie(vertex* trie, int size)
  17. {
  18.     for (int i = 0; i < size; ++i)
  19.     {
  20.         trie[i].is_terminal = false;
  21.         trie[i].parent = -1;
  22.         trie[i].link = -1;
  23.         trie[i].depth = 0;
  24.         for (int j = 0; j < 26; ++j)
  25.         {
  26.             trie[i].next[j] = -1;
  27.             trie[i].go[j] = -1;
  28.         }
  29.     }
  30. }
  31.  
  32. void add_string(std::string s, int s_len, vertex* trie, int& size, int start)
  33. {
  34.  
  35.     int v = 0;
  36.     int c_idx;
  37.     vertex buff;
  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].parent = v;
  49.             trie[size].parent_char = c;
  50.             trie[v].next[c_idx] = size++;
  51.         }
  52.  
  53.         v = trie[v].next[c_idx];
  54.     }
  55.     trie[v].is_terminal = true;
  56.     trie[v].depth = s_len;
  57.     trie[v].start = start;
  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. void fill_trie(int p_len, std::string P, vertex* trie, int& trie_size, int& count)
  95. {
  96.  
  97.     clean_trie(trie, 26 * p_len);
  98.  
  99.     int i = 0;
  100.     int start = 0;
  101.     std::string mask;
  102.     int len_mask;
  103.     while (i < p_len)
  104.     {
  105.         if (P[i] == '?')
  106.         {
  107.             if (i - start > 0)
  108.             {
  109.                 len_mask = i - start;
  110.                 mask = P.substr(start, len_mask);
  111.                 add_string(mask, len_mask, trie, trie_size, start);
  112.                 count++;
  113.             }
  114.  
  115.             start = i + 1;
  116.         }
  117.  
  118.         else if (i == p_len - 1)
  119.         {
  120.             len_mask = i - start + 1;
  121.             mask = P.substr(start, len_mask);
  122.             add_string(mask, len_mask, trie, trie_size, start);
  123.             count++;
  124.         }
  125.         i++;
  126.     }
  127. }
  128.  
  129. void search_pattern(int t_len, vertex* trie, std::string T, int& count, int p_len)
  130. {
  131.  
  132.  
  133.     if (count == 0)
  134.     {
  135.         count = t_len - p_len + 1;
  136.         std::cout << count << std::endl;
  137.         for (int i = 0; i < count; ++i)
  138.             std::cout << i << " ";
  139.     }
  140.  
  141.     else
  142.     {
  143.         char c;
  144.         int v = 0;
  145.         int u;
  146.         int c_idx;
  147.         int start = 0;
  148.  
  149.         int C[t_len];
  150.         int count_pos = 0;
  151.  
  152.         for (int i = 0; i < t_len; ++i)
  153.             C[i] = 0;
  154.  
  155.         for (int i = 0; i < t_len; ++i)
  156.         {
  157.             c = T[i];
  158.             c_idx = static_cast<int>(c) - 97;
  159.  
  160.             if (trie[v].next[c_idx] == -1)
  161.             {
  162.                 while (v > 0 && trie[v].next[c_idx] == -1)
  163.                 {
  164.                     v = get_suff_link(v, trie);
  165.                 }
  166.  
  167.                 if (trie[v].next[c_idx] != -1)
  168.                 {
  169.                     v = trie[v].next[c_idx];
  170.                 }
  171.             }
  172.  
  173.             else
  174.                 v = trie[v].next[c_idx];
  175.  
  176.             if (trie[v].is_terminal)
  177.             {
  178.                 u = v;
  179.                 while (u > 0)
  180.                 {
  181.                     if (trie[u].is_terminal)
  182.                     {
  183.                         int idx = i - trie[u].depth + 1 - trie[u].start;
  184.                         if (++C[idx] == count && (p_len + idx - 1 < t_len) && idx >= 0)
  185.                         {
  186.                             count_pos++;
  187.                         }
  188.                     }
  189.                     u = get_suff_link(u, trie);
  190.                 }
  191.             }
  192.         }
  193.  
  194.         std::cout << count_pos << std::endl;
  195.         for (int i = 0; i < t_len; ++i)
  196.             if (C[i] == count && (p_len + i - 1 < t_len))
  197.                 std::cout << i << " ";
  198.     }
  199. }
  200.  
  201. int main()
  202. {
  203.  
  204.     std::string P, T;
  205.     // std::cin >> P >> T;
  206.     // P = "he?she?his?hers";
  207.     // P = "he?she";
  208.     // P = "abcd";
  209.     // T = "heashe";
  210.  
  211.     //Если убрать первый ? то ошибка уходит (!)
  212.     P = "a?";
  213.     T = "aaa";
  214.  
  215.     // P = "?a";
  216.     // T = "aaaa";
  217.  
  218.  
  219.     int p_len = P.length();
  220.     int t_len = T.length();
  221.  
  222.     int trie_size = 1;
  223.     int max_size = 26 * p_len;
  224.     vertex trie[max_size];
  225.     int count = 0;
  226.     fill_trie(p_len, P, trie, trie_size, count);
  227.  
  228.     search_pattern(t_len, trie, T, count, p_len);
  229.  
  230.  
  231.     return 0;
  232. }
  233.  
Add Comment
Please, Sign In to add comment