AC自动机+uva1449

来源:互联网 发布:pop culture 书单 知乎 编辑:程序博客网 时间:2024/05/04 20:11

AC自动机适用于多模式串

#include<iostream>#include<cstdio>#include<queue>#include<cstring>#include<map>#include<string>using namespace std;const int maxn=1000000;int n;char text[1000010];char p[155][80];map<string,int> m;struct AC{    int ch[maxn][30];    int val[maxn];    int sz;    int f[maxn],last[maxn];    int cnt[maxn];    void init(){sz=1;memset(ch[0],0,sizeof(ch[0]));memset(cnt,0,sizeof(cnt));m.clear();}    int idx(char x){return x-'a';}    void insert(char *s,int v)    {        int u=0,len=strlen(s);        for(int i=0;i<len;i++)        {            int c=idx(s[i]);            if(!ch[u][c])            {                memset(ch[sz],0,sizeof(ch[sz]));                val[sz]=0;                ch[u][c]=sz++;            }            u=ch[u][c];        }        val[u]=v;        m[string(s)]=v;    }    void getFail()    {        queue<int> q;        f[0]=0;        for(int i=0;i<26;i++)        {            int u=ch[0][i];            if(u){f[u]=0,last[u]=0;q.push(u);}        }        while(!q.empty())        {            int r=q.front();q.pop();            for(int i=0;i<26;i++)            {                int u=ch[r][i];                if(!u){ch[r][i]=ch[f[r]][i];continue;}                q.push(u);                int v=f[r];                while(v&&!ch[v][i])v=f[v];                f[u]=ch[v][i];                last[u]=val[f[u]]?f[u]:last[f[u]];            }        }    }    void find(char *t)    {        int len=strlen(t);        int j=0;        for(int i=0;i<len;i++)        {            int c=idx(t[i]);            j=ch[j][c];            if(val[j])print(j);            else if(last[j])print(last[j]);        }    }    void print(int j)    {        if(j)        {            cnt[val[j]]++;            print(last[j]);        }    }}ac;int main(){    //freopen("in.txt","r",stdin);    while(scanf("%d",&n)!=EOF&&n)    {        getchar();        ac.init();        for(int i=1;i<=n;i++)        {            scanf("%s",p[i]);            ac.insert(p[i],i);        }        getchar();        scanf("%s",text);        ac.getFail();        ac.find(text);        int best=-1;        for(int i=1;i<=n;i++)        {            if(ac.cnt[i]>best)best=ac.cnt[i];        }        printf("%d\n",best);        for(int i=1;i<=n;i++)            if(ac.cnt[m[string(p[i])]]==best)printf("%s\n",p[i]);    }    return 0;}


0 0
原创粉丝点击