Advertisement
Guest User

Aho

a guest
Jun 23rd, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.00 KB | None | 0 0
  1. ///Finding the number of occurs of a string in another string
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. #define ll long long int
  5. vector<string>vs;
  6.  
  7. struct NODE
  8. {
  9.     ll cnt,i;
  10.     bool vis;
  11.     NODE *next[60];
  12.     vector<NODE *> out;
  13.     NODE()
  14.     {
  15.         cnt=0;
  16.         vis=false;
  17.         out.clear();
  18.         for(i=0; i<60; i++)
  19.             next[i]=NULL;
  20.     }
  21.  
  22.     ~NODE()
  23.     {
  24.         for(i=0; i<60; i++)
  25.             if(next[i])
  26.                 delete(next[i]);
  27.     }
  28. };
  29.  
  30. NODE *root,*p;
  31.  
  32. void aho_corasick(string s)
  33. {
  34.     ll i,c;
  35.     p=root;
  36.     for(i=0; i<s.size(); i++)
  37.     {
  38.         c=s[i]-'A'+1;
  39.         while(!p->next[c])
  40.             p=p->next[0];
  41.         p=p->next[c];
  42.         p->cnt++;
  43.     }
  44. }
  45.  
  46. void buildtrie()
  47. {
  48.     ll i,j,c;
  49.     NODE *u,*w,*v;
  50.     root=new NODE;
  51.     queue< NODE* > q;
  52.  
  53.     ///usual trie part
  54.     for(i=0; i<vs.size(); i++)
  55.     {
  56.         p=root;
  57.         for(j=0; j<vs[i].size(); j++)
  58.         {
  59.             c=vs[i][j]-'A'+1;
  60.             if(!p->next[c])
  61.                 p->next[c]=new NODE;
  62.             p=p->next[c];
  63.         }
  64.     }
  65.  
  66.     /// Pushing the nodes adjacent to root into queue
  67.     for(i=0; i<60; i++)
  68.     {
  69.         if(root->next[i])
  70.         {
  71.             q.push(root->next[i]);
  72.             root->next[i]->next[0]=root; /// ->next[0] = back Pointer
  73.         }
  74.         else
  75.             root->next[i]=root;
  76.     }
  77.  
  78.     ///Building Aho-Corasick tree
  79.     while(!q.empty())
  80.     {
  81.         u=q.front(); /// parent node
  82.         q.pop();
  83.  
  84.         for(i=1; i<60; i++)
  85.         {
  86.             if(u->next[i])
  87.             {
  88.                 v=u->next[i]; /// child node
  89.                 w=u->next[0]; /// back pointer of parent node
  90.  
  91.                 while(!w->next[i]) /// Until the char(i+'a'-1) child is found
  92.                     w=w->next[0];  /// go up and up to back pointer.
  93.  
  94.                 w=w->next[i];
  95.                 v->next[0]=w;  /// back pointer of v will be found child above.
  96.                 w->out.push_back(v); /// out will be used in dfs step.
  97.                 ///here w is the new found match node.
  98.                 q.push(v);
  99.             }
  100.         }
  101.     }
  102. }
  103.  
  104.  
  105.  
  106. ll dfs(NODE *p)      /// DFS for counting.
  107. {
  108.     ll i;
  109.     if(p->vis)
  110.         return p->cnt;
  111.     for(i = 0; i < p->out.size(); i++)
  112.         p->cnt += dfs(p->out[i]);
  113.     p->vis = true;
  114.     return p->cnt;
  115. }
  116.  
  117. int main()
  118. {
  119.     ll T,t,n,i,j,c;
  120.     string s1,s2;
  121.     scanf("%lld",&T);
  122.     for (t = 1; t <= T; t++)
  123.     {
  124.         scanf("%lld",&n);
  125.         cin>>s1;
  126.         vs.clear();
  127.         for(i=0; i<n; i++)
  128.         {
  129.             cin>>s2;
  130.             vs.push_back(s2);
  131.         }
  132.         buildtrie();
  133.         aho_corasick(s1);
  134.  
  135.         printf("Case %d:\n",t);
  136.  
  137.         for(i=0; i<n; i++)
  138.         {
  139.             p=root;
  140.             for(j=0; j<vs[i].size(); j++)
  141.             {
  142.                 c=vs[i][j]-'A'+1;
  143.                 p=p->next[c];
  144.             }
  145.             printf("%lld\n", dfs(p));
  146.         }
  147.     }
  148.     return 0;
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement