vadimk772336

починил

Mar 19th, 2022
754
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.39 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  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(std::string s, int s_len, vertex* trie, int& size, int end)
  37. {
  38.  
  39.     int v = 0;
  40.     int c_idx;
  41.     vertex buff;
  42.     char c;
  43.  
  44.     for (int i = 0; i < s_len; ++i)
  45.     {
  46.         c = s[i];
  47.         c_idx = static_cast<int>(c) - 97;
  48.  
  49.         if (trie[v].next[c_idx] == -1)
  50.         {
  51.             trie[size].link = -1;
  52.             trie[size].parent = v;
  53.             trie[size].parent_char = c;
  54.             trie[v].next[c_idx] = size++;
  55.         }
  56.  
  57.         v = trie[v].next[c_idx];
  58.     }
  59.     trie[v].is_terminal = true;
  60.     trie[v].depth = s_len;
  61.     trie[v].end.push_back(end);
  62.     trie[v].len_end++;
  63. }
  64.  
  65. int get_link(int v, char c, vertex* trie);
  66.  
  67. int get_suff_link(int v, vertex* trie)
  68. {
  69.     if (trie[v].link == -1)
  70.     {
  71.         if (v == 0 || trie[v].parent == 0)
  72.             trie[v].link = 0;
  73.         else
  74.             trie[v].link = get_link(get_suff_link(trie[v].parent, trie), trie[v].parent_char, trie);
  75.     }
  76.     return trie[v].link;
  77. }
  78.  
  79. int get_link(int v, char c, vertex* trie)
  80. {
  81.  
  82.     int c_idx = static_cast<int>(c) - 97;
  83.  
  84.     if (trie[v].go[c_idx] == -1)
  85.     {
  86.         if (trie[v].next[c_idx] != -1)
  87.             trie[v].go[c_idx] = trie[v].next[c_idx];
  88.  
  89.         else if (v == 0)
  90.             trie[v].go[c_idx] = 0;
  91.  
  92.         else
  93.             trie[v].go[c_idx] = get_link(get_suff_link(v, trie), c, trie);
  94.     }
  95.  
  96.     return trie[v].go[c_idx];
  97. }
  98.  
  99. void fill_trie(int p_len, std::string P, vertex* trie, int& trie_size, int& count)
  100. {
  101.  
  102.     clean_trie(trie, 26 * p_len);
  103.  
  104.     int i = 0;
  105.     int start = 0;
  106.     std::string mask;
  107.     int len_mask;
  108.     while (i < p_len)
  109.     {
  110.         if (P[i] == '?')
  111.         {
  112.             if (i - start > 0)
  113.             {
  114.                 len_mask = i - start;
  115.                 mask = P.substr(start, len_mask);
  116.                 add_string(mask, len_mask, trie, trie_size, i-1);
  117.                 count++;
  118.             }
  119.  
  120.             start = i + 1;
  121.         }
  122.  
  123.         else if (i == p_len - 1)
  124.         {
  125.             len_mask = i - start + 1;
  126.             mask = P.substr(start, len_mask);
  127.             add_string(mask, len_mask, trie, trie_size, i);
  128.             count++;
  129.         }
  130.         i++;
  131.     }
  132. }
  133.  
  134. void search_pattern(int t_len, vertex* trie, std::string T, int& count, int p_len)
  135. {
  136.  
  137.  
  138.     if (count == 0)
  139.     {
  140.         count = t_len - p_len + 1;
  141.         std::cout << count << std::endl;
  142.         for (int i = 0; i < count; ++i)
  143.             std::cout << i << " ";
  144.     }
  145.  
  146.     else
  147.     {
  148.         char c;
  149.         int v = 0;
  150.         int u;
  151.         int c_idx;
  152.         int start = 0;
  153.  
  154.         int C[t_len];
  155.         int count_pos = 0;
  156.  
  157.         for (int i = 0; i < t_len; ++i)
  158.             C[i] = 0;
  159.  
  160.         for (int i = 0; i < t_len; ++i)
  161.         {
  162.             c = T[i];
  163.             c_idx = static_cast<int>(c) - 97;
  164.  
  165.             if (trie[v].next[c_idx] == -1)
  166.             {
  167.                 while (v > 0 && trie[v].next[c_idx] == -1)
  168.                 {
  169.                     v = get_suff_link(v, trie);
  170.                 }
  171.  
  172.                 if (trie[v].next[c_idx] != -1)
  173.                 {
  174.                     v = trie[v].next[c_idx];
  175.                 }
  176.             }
  177.  
  178.             else
  179.                 v = trie[v].next[c_idx];
  180.  
  181.  
  182.             u = v;
  183.             while (u > 0)
  184.             {
  185.                 if (trie[u].is_terminal)
  186.                 {
  187.                     for (int k = 0; k < trie[u].len_end; ++k)
  188.                     {
  189.                         int idx = i - trie[u].end[k];
  190.                         C[idx]++;
  191.                         if (idx >= 0  && idx < t_len && C[idx] == count)
  192.                         {
  193.                             count_pos++;
  194.                         }
  195.                     }
  196.  
  197.                 }
  198.                 u = get_suff_link(u, trie);
  199.             }
  200.            
  201.         }
  202.  
  203.         std::cout << count_pos << std::endl;
  204.         for (int i = 0; i < t_len; ++i)
  205.             if (C[i] == count && (p_len + i - 1 < t_len))
  206.                 std::cout << i << " ";
  207.     }
  208. }
  209.  
  210. int main()
  211. {
  212.  
  213.     std::string P, T;
  214.     //std::cin >> P >> T;
  215.     T = "dbaddabdbadadddbabddbddbbdaaddaddbdbdbdaddbdbdddbddddabddddadbdadddaadddbbbddbddddbbaddbdbdddddbddbabdabddadaadbdddddbabdadbbabaddbdaadddddadddbaaadbadadbadddddabddddaadbdbadaddbdaaddaddadbdbdabbdadbd";
  216.     P = "d????adbd?";
  217.     //T = "addaddadbdb";
  218.     //P = "a?a?s?a";
  219.     //T = "aaaasaasdravabssa";
  220.     int p_len = P.length();
  221.     int t_len = T.length();
  222.     //T = T.substr(161,t_len-161);
  223.     //std::cout << T << endl;
  224.     t_len = T.length();
  225.  
  226.     int count = 0;
  227.     int trie_size = 1;
  228.     int max_size = 26 * p_len;
  229.     vertex trie[max_size];
  230.    
  231.     fill_trie(p_len, P, trie, trie_size, count);
  232.    
  233.     search_pattern(t_len, trie, T, count, p_len);
  234.  
  235.     return 0;
  236. }
  237.  
Advertisement
Add Comment
Please, Sign In to add comment