hdu2222(AC自动机入门)

来源:互联网 发布:西南大学网络教育如何 编辑:程序博客网 时间:2024/05/21 01:44

http://acm.hdu.edu.cn/showproblem.php?pid=2222

AC自动机--------字典树+KMP原理

挺有趣的。

#include <stdio.h>#include <string.h>#include <math.h>#include <queue>#include<iostream>using namespace std;#define N 500010#define MAXN 1000010char str[MAXN],keyword[51];int head,tail;struct node{    node *fail;    node *next[26];    int cnt;    node(){        fail=NULL;        cnt=0;        for(int i=0;i<26;i++) next[i]=NULL;    }}*q[N];node *root;void insert(char *str){//建树    int temp,len;    node *p=root;    len = strlen(str);    for(int i=0;i<len;i++){        temp=str[i]-'a';        if(p->next[temp]==NULL)            p->next[temp]=new node();        p=p->next[temp];//printf("1?\n");    }//for    p->cnt++;}//insertvoid build_ac(){//初始化fail指针,BFS    q[tail++]=root;    while(head!=tail){        node *p=q[head++];//弹出队头        node *temp=NULL;        for(int i=0;i<26;i++){            if(p->next[i]!=NULL){                if(p==root)  p->next[i]->fail=root;//第一个元素fail必指向根                else{                    temp = p->fail;//失败指针                    while(temp!=NULL){                        if(temp->next[i]!=NULL){p->next[i]->fail=temp->next[i];break;}//找到匹配                        temp=temp->fail;                    }//while                    if(temp==NULL) p->next[i]->fail=root;//为空则从头匹配                }//else                q[tail++] =p->next[i];//入列            }//if        }//for    }//while}//build_acint query(){    int index, len, res;    node *p=root;//Tire入口    res=0;//ext    len=strlen(str);    for(int i=0;i<len;i++){        index = str[i]-'a';        while(p->next[index]==NULL&&p!=root) p=p->fail;//跳转失败指针        p=p->next[index];        if(p==NULL) p=root;        node *temp=p;//p不动,temp计算缀串        while(temp != root && temp->cnt!=-1){            res+=temp->cnt;            temp->cnt=-1;            temp=temp->fail;        }//while    }//for    return res;}//queryint main(){    int T,num;    scanf("%d",&T);    while(T--){        head=tail=0;        root = new node();        scanf("%d",&num);        getchar();        for(int i=0;i<num;i++){            gets(keyword);            insert(keyword);        }//for        build_ac();        scanf("%s",str);        printf("%d\n",query());    }//while    return 0;}


0 0