Advertisement
Matrix_code

strings - Aho-Corasick

May 19th, 2016 (edited)
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.90 KB | None | 0 0
  1. /************************************************************************
  2.  *                    Aho-corasick Implementation                        *
  3.  *                                                                       *
  4.  *  Given some dictionary and Text. Output The occurances of each
  5.  dictionary in the Text in O(|T| + |S|)
  6.  *   Memory : |S|
  7.  *   Implementation :
  8.  * Insert each dictionary in trie
  9.  * Now scan through the text. If there is transition,then make,
  10.  * or look for alternative by going to suffix link
  11.  # to => transition, link => greatest suffix link
  12.  * init()
  13.  * insert()
  14.  * fail()
  15.  # The below code output the # of occurance of each dictionary
  16.  **************************************************************************/
  17. #include <bits/stdc++.h>
  18. using namespace std;
  19.  
  20. const int N = 25e4+4;
  21. const int SIGMA = 26;
  22. int Map[505];
  23. namespace Aho{
  24.     int to[N][SIGMA], link[N] , go;
  25.     int nc[N];
  26.     vector<int>VQ;
  27.     void init()
  28.     {
  29.         memset(link,0,sizeof link);
  30.         memset(to,0,sizeof to);
  31.         memset(nc,0,sizeof nc);
  32.         VQ.clear();
  33.         go = 1;
  34.     }
  35.     void insert(char s[],int k)
  36.     {
  37.         int cur = 0;
  38.         for(int i= 0; s[i];i ++ ) {
  39.             int c = s[i]-'a';
  40.             if(!to[cur][c]){
  41.                 to[cur][c] = go ++;
  42.             }
  43.             cur = to[cur][c];
  44.         }
  45.         Map[k] = cur;
  46.     }
  47.     void fail()
  48.     {
  49.         queue<int>q;
  50.         for(int c = 0 ; c< SIGMA; c ++) {
  51.             if(to[0][c]) q.push(to[0][c]);
  52.             else to[0][c] = 0;
  53.         }
  54.         while(!q.empty()){
  55.             int u = q.front(); q.pop();
  56.             for(int c = 0; c < SIGMA; c ++ ) {
  57.                 if(!to[u][c]) {
  58.                     to[u][c]= to[link[u]][c];
  59.                 }
  60.                 else {
  61.                     int v = to[u][c];
  62.                     link[v] = to[link[u]][c];
  63.                     q.push(v);
  64.                     VQ.push_back(v);
  65.                 }
  66.             }
  67.         }
  68.     }
  69.     void find(char s[])
  70.     {
  71.         for(int i = 0, j = 0; s[i] ;  i ++ ) {
  72.             int c = s[i]-'a';
  73.             while(j>0&&!to[j][c]) j = link[j];
  74.             if(to[j][c]) j = to[j][c];
  75.             nc[j] ++;
  76.         }
  77.     }
  78.     void calc()
  79.     {
  80.         reverse(VQ.begin(), VQ.end());
  81.         for(int i = 0; i < VQ.size(); i ++ ) {
  82.             nc[link[VQ[i]]] += nc[VQ[i]];
  83.         }
  84.     }
  85.    
  86. };
  87. char T[1000006];
  88. char s[505];
  89.  
  90. int main()
  91. {
  92.     int t,cs=0,n;
  93.     scanf("%d",&t);
  94.     while(t--){
  95.         scanf("%d",&n);
  96.         scanf("%s",T);
  97.         Aho::init();
  98.         memset(Map,0,sizeof Map);
  99.         for(int i = 0; i < n; i ++ ){
  100.             scanf("%s",s);
  101.             Aho::insert(s,i);
  102.         }
  103.         Aho::fail();
  104.         Aho::find(T);
  105.         Aho::calc();
  106.         printf("Case %d:\n",++cs);
  107.         for(int i = 0; i < n ; i ++ ) printf("%d\n", Aho::nc[Map[i]]);
  108.     }
  109.    
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement