垃圾ac自动模板

来源:互联网 发布:在哪看淘宝自动售货 编辑:程序博客网 时间:2024/05/18 01:28

于是现在才会写自动机一定是要遭人嘲笑得了。


#include<cstdio>#include<cstdlib>#include<iostream> #include<cstring>#include<string>#include<queue>#include<map>#include<algorithm>#define  Clear(s) memset((s),0,sizeof((s)))using namespace std;const int N = 1000010;const int M = 1000010;struct AC{    int ch[N][26],f[N],last[N];    int val[N],cnt[N];    int top;   void init(){        Clear(ch); Clear(f); Clear(last);        Clear(val); Clear(cnt);        top = 0;        }        void insert(char *T, int num){        int n = strlen(T);        int x = 0;        for(int i = 0; i < n; i++){            int c = T[i]-'a';            if( !ch[x][c] ) ch[x][c] = ++top;            x = ch[x][c];        }        val[x] = num;//说明这个是某个字串的末尾。。。        }    void getfail(){        queue<int> Q;        for(int c = 0; c < 26; c++){            int u = ch[0][c];            if(u) f[u] = 0, last[u] = 0, Q.push(u);        }        while( !Q.empty() ){            int r = Q.front(); Q.pop();            for(int c = 0; c < 26; c++){                int u = ch[r][c];            //    if( !u ) continue;                if( !u ){ ch[r][c] = ch[ f[r] ][c]; continue; } //补上所有不存在的边                Q.push(u);                    int v = f[r];                while( v && !ch[v][c] ) v = f[v];                f[u] = ch[v][c];                        //        printf("f[%d] = ch[%d][%d] = %d\n", u,v,c, f[u] );                last[u] = val[ f[u] ] ? f[u]: last[ f[u] ];            }        }        }    void find(char *T){        int n = strlen(T);        int x = 0;        for(int i = 0; i < n; i++){            int c = T[i]-'a';        //    while( x && !ch[x][c] ) x = f[x];                x = ch[x][c]; //直接匹配到                //    printf("Find: x = %d\n", x );            if( val[x] ) count(x);            else if( last[x] ) count(last[x]);//?? 这个地方似乎写f[x],x都行,,,        }    }    void count(int x){        if(x){//            printf("Count: x = %d\n", x );                cnt[ val[x] ]++;            if( last[x] ) count( last[x] );        }        }}ac;map<string,int> mp;char str[20000][100];char text[M];int main(){    int n;    int T;cin>>T;    while(T--)    {scanf("%d",&n);       mp.clear();ac.init();        int tot = 0;        for(int i = 1; i <= n; i++){            scanf("%s", str[i] );            if( mp.count( str[i] ) == 0 ) mp[ str[i] ] = ++tot;                        ac.insert( str[i], mp[str[i]] );        }        ac.getfail();            scanf("%s", text);        ac.find( text );                int k = 0;        for(int i = 1; i <= tot; i++) k+=ac.cnt[i];            // k = max( k, ac.cnt[i] );        printf("%d\n", k );      /*  for(int i = 1; i <= n; i++){            if( ac.cnt[ mp[str[i]] ] == k )                printf("%s\n", str[i] );        }*/    }    return 0;}

0 0