hdu 2896 ac自动机

来源:互联网 发布:nike淘宝旗舰店 编辑:程序博客网 时间:2024/05/17 06:05

n个子串,m个母串,在母串中找子串是否出现过。 格式输出 输入有空格  可见字符 ascii是33~126

Sample Input

3aaabbbccc2aaabbbcccbbaacc

Sample Output
web 1: 1 2 3total: 1



#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node{int num;   //标记子串的尾巴node *next[129],*fail;node(){num=0;fail=NULL;for(int i=32;i<127;i++)next[i]=NULL;}}*q[1000010]; //创建ac树的时候的队列char ss[21000],s[111111];//s是n个子串  ss是母串void insert(char s[],node *root,int pos){int len=strlen(s); //printf("! len=%d pos=%d\n",len,pos);node *p=root;for(int i=0;i<len;i++){  //创建树if(p->next[s[i]]==NULL)p->next[s[i]]=new node();p=p->next[s[i]];}p->num=pos;  }int que[1111111],it;void acmove(node *root){  //创建ac树 即 失败指针int head=0,tail=1;root->fail=NULL;q[0]=root;while(head!=tail){node *now=q[head++];node *p=NULL;for(int i=32;i<127;i++){if(now->next[i]!=NULL){if(now==root) now->next[i]->fail=root;else{p=now->fail;while(p!=NULL){if(p->next[i]!=NULL){now->next[i]->fail=p->next[i];break;}p=p->fail;}if(p==NULL)now->next[i]->fail=root;}q[tail++]=now->next[i];}}}}void find(node *root){  //对母串进行查找int i=0,numb=0,len=strlen(ss);node *p=root;while(ss[i]){while(p->next[ss[i]]==NULL&&p!=root)p=p->fail;p=p->next[ss[i]];p=(p==NULL)?root:p;node *now=p;while(now!=root&&now->num!=0){que[it++]=now->num;now=now->fail;}i++;}}int main(){int n,m;while(scanf("%d",&n)!=EOF){getchar();node *root;root=new node();for(int i=1;i<=n;i++){gets(s);insert(s,root,i);//printf("! i=%d s=%s\n",i,s);}int sum=0;acmove(root);scanf("%d",&m);getchar();for(int i=1;i<=m;i++){gets(ss);it=1;find(root);if(it-1){sort(que,que+it);printf("web %d:",i);for(int j=1;j<it;j++){if(que[j]!=que[j-1])printf(" %d",que[j]);}printf("\n");sum++;}}printf("total: %d\n",sum);//printf("! m=%d n=%d\n",m,n);}return 0;}



原创粉丝点击