hdu 2222

来源:互联网 发布:淘宝管控记录何时清除 编辑:程序博客网 时间:2024/04/29 04:00


AC自动机

要求对一个文本统计出现过的模板个数

理解了AC自动机的算法就很容易了


指针版

#include<queue>#include<stdio.h>#include<iostream>#include<cstdio>using namespace std;struct node{    int fl;    node *next[26],*fail;    node(){        memset(next,0,sizeof next);        fail=NULL;        fl=0;            }};char s[1000050],ss[1005];void ins(node *rt,char mb[]){    int i=0,x;    node *tmp=rt;    while(mb[i]){        x=mb[i]-'a';        if(tmp->next[x]==NULL)tmp->next[x]=new node();        tmp=tmp->next[x];        i++;    }    tmp->fl++;}queue<node *>q;void build(node *rt){    node *tmp;    q.push(rt);    while(!q.empty()){        tmp=q.front();        q.pop();        for(int i=0;i<26;++i)            if(tmp->next[i]){              q.push(tmp->next[i]);              node *p=tmp->fail;                while(p){                    if(p->next[i]){                        tmp->next[i]->fail=p->next[i];                        break;                    }                    p=p->fail;                }                if(!p)tmp->next[i]->fail=rt;            }    }}int query(node *rt){    int i=0,cnt=0,x;    node *tmp=rt;    while(s[i]){        x=s[i]-'a';        while(!tmp->next[x]&&tmp!=rt)tmp=tmp->fail;        tmp=tmp->next[x];        if(!tmp)tmp=rt;        node *p=tmp;                while(p&&p->fl!=-1){            cnt+=p->fl;            p->fl=-1;            p=p->fail;        }        i++;    }        return cnt;}int main(){    int n;    int t;scanf("%d",&t);    while(t--){        scanf("%d",&n);        node *root=new node();        for(int i=0;i<n;++i){            scanf("%s",ss);            ins(root,ss);        }        build(root);        scanf("%s",s);        printf("%d\n",query(root));    }    return 0;}
数组版:(注意C++会TLE 可能与内存分配有关)
#include<iostream>#include<stdio.h>#include<cstdio>#include<queue>using namespace std;#define M 510000#define size 26struct node{    int ch[M][26],fail[M],end[M],cnt,root;    int add(){        ++cnt; memset(ch[cnt],-1,sizeof ch[cnt]);        end[cnt]=0;        return cnt;    }    void init(){        cnt=0;root=add();    }    void ins(char s[]){        int len=(int)strlen(s);int p=root;        for(int i=0;i<len;++i){            int x=s[i]-'a';            if(ch[p][x]==-1)ch[p][x]=add();            p=ch[p][x];        }        end[p]++;    }    queue<int>q;    void build(){        int p=root;fail[root]=root;        for(int i=0;i<size;++i){            if(ch[p][i]==-1) ch[p][i]=p;            else { q.push(ch[p][i]); fail[ch[p][i]]=p;}        }        while(!q.empty()){            p=q.front();q.pop();            for(int i=0;i<size;++i){                if(ch[p][i]==-1) ch[p][i]=ch[fail[p]][i];                else{fail[ch[p][i]]=ch[fail[p]][i]; q.push(ch[p][i]);}            }        }    }    void query(char s[]){        int len=(int)strlen(s),pos=root,ans=0;        for(int i=0;i<len;++i){            int x=s[i]-'a';            int tmp=ch[pos][x]; pos=tmp;            while(tmp!=root){                ans+=end[tmp];end[tmp]=0;tmp=fail[tmp];            }        }        printf("%d\n",ans);    }}x;char s1[1005],s2[1100000];int main(){    int t,n;scanf("%d",&t);    while(t--){        scanf("%d",&n);x.init();        for(int i=0;i<n;++i){            scanf("%s",s1);            x.ins(s1);        }        x.build();        scanf("%s",s2);        x.query(s2);    }    return 0;}


0 0
原创粉丝点击