Hdu 2222 Keywords Search [AC自动机多模匹配]

来源:互联网 发布:算法导论epub中文版 编辑:程序博客网 时间:2024/05/29 19:07

题目链接:点击打开链接

AC自动机裸题,有待进一步理解。

代码:

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <queue>using namespace std;const int N=55;const int M=1000003;const int H=26;char str[M];struct Node{    Node *fail;    Node *next[H];    int cnt;    Node(){        fail=NULL;        cnt=0;        memset(next,0,sizeof(next));    }}*root;void Save(char *s){//构造字典树.    int len=strlen(s);    if(len==0) return ;    Node *p=root;    for(int i=0;i<len;i++){        int k=s[i]-'a';        if(p->next[k]==NULL)        p->next[k]=new Node();        p=p->next[k];    }    p->cnt++;}void Build_Fail(){//构造失败指针.    queue<Node*> q;    root->fail=NULL;//指向NULL和根节点的区别.    q.push(root);    while(!q.empty()){        Node *tmp=q.front(),*p=NULL;//指针null就是0.        for(int i=0;i<H;i++){            if(tmp->next[i]!=NULL){                if(tmp==root){//如果的根节点的儿子的话,fail指针指向root.                    tmp->next[i]->fail=root;                }                else {//不是根节点的儿子的话.                    p=tmp->fail;                    while(p!=NULL){                        //沿着父亲节点的fail指针寻找与其相同字符.                        if(p->next[i]!=NULL){                            tmp->next[i]->fail=p->next[i];                            break;                        }                        p=p->fail;                    }                    //如果不存在则指向root.                    if(p==NULL) tmp->next[i]->fail=root;                }                q.push(tmp->next[i]);            }        }        q.pop();    }}int AC(){//与主串进行匹配.擦,不是很了解.    int ans=0,len=strlen(str);    Node *p=root;    for(int i=0;i<len;i++){        int k=str[i]-'a';        while(p->next[k]==NULL&&p!=root) p=p->fail;//跳转失败指针.        p=p->next[k];        p=(p==NULL)?root:p;//如果失配,那么指向        Node *tmp=p;        while(tmp!=root&&tmp->cnt!=-1){            ans+=tmp->cnt;            tmp->cnt=-1;            tmp=tmp->fail;        }    }    return ans;}int main(){//    freopen("1.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--){        int n;        scanf("%d",&n);        char word[N];        root=new Node();        for(int i=1;i<=n;i++){            scanf("%s",word);            Save(word);        }        Build_Fail();        scanf("%s",str);        printf("%d\n",AC());    }    return 0;}


0 0