hdu-2222-Keywords Search(AC自动机)

来源:互联网 发布:电子杂志用什么软件 编辑:程序博客网 时间:2024/06/03 07:12

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222

题意:多模式匹配,给出多个模式串一个文本串,看模式串在文本串

中出现了多少个,AC自动机的模板题目。

code:

#include<iostream>#include<cstdio>#include<queue>using namespace std;const int maxn = 26;struct node{    int cut;    node *son[maxn];    node *fail;    node(){        for(int i=0;i<maxn;i++)            son[i]=NULL;        fail=NULL;cut=0;    }};node *root;void Insert(char *str)  ///建树{    node *p=root,*q;    int i=0;    while(str[i]!='\0'){        int id = str[i]-'a';        if(p->son[id]!=NULL){            p=p->son[id];        }else {            q=new node;            p->son[id]=q;            p=q;        }        i++;    }    p->cut++;}void fail_build() ///求fail指针,,构建AC自动机。{    node *p=root;    queue <node *> qu;    qu.push(p);    while(!qu.empty()){        p=qu.front();        qu.pop();        for(int i=0;i<maxn;i++)        {            if(p->son[i]!=NULL)            {                if(p==root)   ///如果为根 那么它的fail指针都指向根                    p->son[i]->fail=root;                else                {                    node *temp=p->fail;                    while(temp!=NULL){                        if(temp->son[i]!=NULL){                            p->son[i]->fail=temp->son[i];                            break;                        }                        temp=temp->fail;                    }                    if(temp==NULL)  /// 只有根fail指针为空,所以指向向根                        p->son[i]->fail=root;                }                qu.push(p->son[i]);            }        }    }}int AC_Find(char *str)  ///匹配函数{    node *p=root;    int i=0,ans=0;    while(str[i]!='\0'){        int id = str[i]-'a';        while(p->son[id]==NULL&&p!=root)            p=p->fail;        p=p->son[id];        if(p==NULL) p=root;        node *temp= p;        while(temp!=NULL&&temp->cut!=-1){            ans+=temp->cut;            temp->cut=-1;            temp=temp->fail;        }        i++;    }    return ans;}void del(node *p) ///销毁字典树{    for(int i=0;i<maxn;i++)        if(p->son[i]!=NULL)            del(p->son[i]);    delete(p);}int main(){    int t,n;    char str1[50],str[1000000];    scanf("%d",&t);    while(t--){        scanf("%d",&n);        root =new node;        while(n--){            scanf("%s",str1);            Insert(str1);        }        fail_build();        scanf("%s",str);        printf("%d\n",AC_Find(str));        del(root);    }    return 0;}


原创粉丝点击