Advertisement
Guest User

Untitled

a guest
Oct 21st, 2017
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.83 KB | None | 0 0
  1. /**
  2.  * Author             : Dipu Kumar Mohanto (Dip)
  3.  *                      CSE, BRUR.
  4.  *
  5.  * Problem            : 1427 - Substring Frequency (II)
  6.  * Algorithm          : Aho - Corasik
  7.  * Complexity         : O(q*(len+|p|)
  8.  * Category           : String, string matching
  9.  *
  10.  * Source             : LIGHT Online Judge
  11.  *
  12.  * Verdict            : Accepted
  13.  *
  14.  * Date               :
  15.  * E-mail             : dipukumarmohanto1@gmail.com
  16. **/
  17.  
  18. #include <bits/stdc++.h>
  19.  
  20. using namespace std;
  21.  
  22. const int mx = 510;
  23.  
  24. struct node {
  25.     int cnt;
  26.     bool vis;
  27.  
  28.     node* next[27];
  29.  
  30.     vector <node *> out;
  31.  
  32.     node() {
  33.         cnt = 0;
  34.         vis = false;
  35.  
  36.         for (int i=0; i<27; i++)
  37.             next[i] = NULL;
  38.  
  39.         out.clear();
  40.     }
  41.  
  42.     ~node() {
  43.         for (int i=1; i<27; i++) {
  44.             if (next[i] != NULL && next[i] != this)
  45.             {
  46.                 delete next[i];
  47.             }
  48.         }
  49.     }
  50. }*root;
  51.  
  52.  
  53. void buildTrie(char dictionary[][mx], int n)
  54. {
  55.     // dictionary[][] = all query word
  56.     // n              = total query word
  57.  
  58.     root = new node();
  59.  
  60.     // usual trie tree
  61.     for (int i=0; i<n; i++)
  62.     {
  63.         node* a = root;
  64.  
  65.         for (int j=0; dictionary[i][j]; j++)
  66.         {
  67.             int id = dictionary[i][j] - 'a' + 1;
  68.  
  69.             if (a->next[id] == NULL)
  70.                 a->next[id] = new node();
  71.  
  72.             a = a->next[id];
  73.         }
  74.     }
  75.  
  76.     // Pushing adjacent node to root into queue
  77.     queue <node *> PQ;
  78.  
  79.     for (int i=0; i<27; i++)
  80.     {
  81.         if (root->next[i] == NULL)
  82.         {
  83.             root->next[i] = root;
  84.         }
  85.  
  86.         else
  87.         {
  88.             PQ.push(root->next[i]);
  89.  
  90.             root->next[i]->next[0] = root;  // ->next[0] = back pointer
  91.         }
  92.     }
  93.  
  94.     //Building Aho - Corasik tree
  95.     while (!PQ.empty())
  96.     {
  97.         node* u = PQ.front();   // parent node
  98.         PQ.pop();
  99.  
  100.         for (int i=1; i<27; i++)
  101.         {
  102.             if (u->next[i])
  103.             {
  104.                 node* v = u->next[i];   // child node
  105.                 node* w = u->next[0];   // back pointer of parent node
  106.  
  107.                 while (!w->next[i])     // untill the char (i - 'a' + 1) child is not found
  108.                     w = w->next[0];
  109.  
  110.                 v->next[0] = w = w->next[i];  // back pointer of v will be found child above
  111.                 w->out.push_back(v);    // out will be used in dfs
  112.                                         // here w is the new found match node
  113.                 PQ.push(v);
  114.             }
  115.         }
  116.     }
  117. }
  118.  
  119.  
  120.  
  121. // Third step processing the text
  122. void aho_corasik(node* p, char *word)
  123. {
  124.     for (int i=0; word[i]; i++)
  125.     {
  126.         int id = word[i] - 'a' + 1;
  127.  
  128.         while (!p->next[id])
  129.             p = p->next[0];
  130.  
  131.         p = p->next[id];
  132.         p->cnt++;
  133.     }
  134. }
  135.  
  136. // DFS for counting
  137. int dfs(node* p)
  138. {
  139.     if (p->vis)
  140.         return p->cnt;
  141.  
  142.     for (int i=0; i<(int)p->out.size(); i++)
  143.         p->cnt += dfs(p->out[i]);
  144.  
  145.     p->vis = true;
  146.  
  147.     return p->cnt;
  148. }
  149.  
  150. char str[1000000 + 100];
  151. char dictionary[mx][mx];
  152.  
  153.  
  154.  
  155. int main()
  156. {
  157.     //freopen("in.txt", "r", stdin);
  158.  
  159.     int tc;
  160.     scanf("%d", &tc);
  161.  
  162.     for (int tcase=1; tcase<=tc; tcase++)
  163.     {
  164.         int Q; // query
  165.         scanf("%d", &Q);
  166.  
  167.         scanf("%s", str);
  168.  
  169.         for (int i=0; i<Q; i++)
  170.             scanf("%s", dictionary[i]);
  171.  
  172.         buildTrie(dictionary, Q);
  173.         aho_corasik(root, str);
  174.  
  175.         printf("Case %d:\n", tcase);
  176.  
  177.         for (int i=0; i<Q; i++)
  178.         {
  179.             node* p = root;
  180.  
  181.             for (int j=0; dictionary[i][j]; j++)
  182.             {
  183.                 int id = dictionary[i][j] - 'a' + 1;
  184.                 p = p->next[id];
  185.             }
  186.             printf("%d\n", dfs(p));
  187.         }
  188.         delete root;
  189.     }
  190.     return 0;
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement