首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

[AC自动机]hdoj 3065:病毒袭击持续中

2012-09-29 
[AC自动机]hdoj 3065:病毒侵袭持续中大致题意:? ? 给出n个模式串,一个文本串,分别求出每个文本串子在模式

[AC自动机]hdoj 3065:病毒侵袭持续中

大致题意:

? ? 给出n个模式串,一个文本串,分别求出每个文本串子在模式串中出现的次数。

?

大致思路:

? ? 基本的AC自动机,要修改一些地方。

?

#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include <algorithm>using namespace std;const int inf=1<<28;const int nMax=1500;const int mMax=2000000;class node{public:    int id;    int count;  //前缀记录标志    node *next[30],*fail;    node(){        id=-1;        count=0;        fail=NULL;        for(int i=0;i<30;i++)next[i]=NULL;    }}*root,*que[mMax];int cnt;void insert(char *s){    //构造前缀树    int i;    node *r=root;    int l=strlen(s);    for(i=0;i<l;i++){        int loc=s[i]-'A';        if(r->next[loc]==NULL){            r->next[loc]=new node();        }        r=r->next[loc];    }    if(r->id==-1){        r->id=cnt;        cnt++;    }    r->count++;}void acAuto(){      //用bfs为每个节点设定fail指针    int i,head=0,tail=0;    node *p,*tmp;    root->fail=NULL;    que[tail++]=root;    while(head<tail){        tmp=que[head++];        for(i=0;i<30;i++){            if(tmp->next[i]==NULL)continue;            if(tmp==root){                tmp->next[i]->fail=root;            }            else {                for(p=tmp->fail;p!=NULL;p=p->fail){                    if(p->next[i]!=NULL){                        tmp->next[i]->fail=p->next[i];                        break;                    }                }                if(p==NULL){                    tmp->next[i]->fail=root;                }            }            que[tail++]=tmp->next[i];        }    }}int vis[nMax];void search(char *msg){    int i,idx;    node *p=root,*tmp;    for(i=0;msg[i];i++){        idx=msg[i]-'A';        if(idx<0||idx>26)idx=27;        while(p->next[idx]==NULL&&p!=root){            p=p->fail;        }        p=p->next[idx];        if(p==NULL)p=root;        for(tmp=p;tmp!=NULL;tmp=tmp->fail){//&&tmp->count!=-1   因为这里需要求的是该字符串出现的次数            if(tmp->id!=-1)vis[tmp->id]++;   //也就是字符需要重复出现,所以这句要注释掉        }    }}char str[nMax][55],text[mMax];int main(){    int n,i,j,flag;    while(scanf("%d",&n)!=EOF){        cnt=1;        root=new node();        memset(vis,0,sizeof(vis));        for(i=1;i<=n;i++){            scanf("%s",str[i]);            insert(str[i]);        }        acAuto();        scanf("%s",text);        search(text);        flag=1;        for(i=1;i<=n;i++){            if(vis[i]!=0){                flag=0;                printf("%s: %d\n",str[i],vis[i]);            }        }        if(flag)printf("\n");    }    return 0;}
?

热点排行