又熟悉了下AC自动机,这题由于有多个文本串,每次访问后不能在trie图上标记已访问过,只能另开一个数组 还有,输出结果前别忘记排序! 代码: #include<iostream> #include<memory.h> #include<string> #include<cstdio> #include<algorithm> #include<math.h> #include<stack> #include<queue> using namespace std; const int MAXN=13000005; struct node { int id; node *next[128],*fail; node() { id=0; fail==NULL; memset(next,0,sizeof(next)); } }; struct node *que[10005]; int index,x,res[500]; char t[100005]; char s; /*node * newnode() { memset(trie+index,0,sizeof(trie[0])); return &trie[index++]; }*/ void insert(char str[],node *root,int id) { int i=0,del,len=strlen(str); node *p=root; for(i=0;i<len;i++) { del=str[i]-31; if(p->next[del]==NULL) { p->next[del]=new node(); } p=p->next[del]; } p->id=id; } void build_fail(node *root) { int head=0,tail=0,i; que[++tail]=root; root->fail=NULL; while(head!=tail) { if(++head==10000) head=0; node *fa=que[head]; for(i=0;i<128;i++) { if(fa->next[i]) { if(fa==root) { fa->next[i]->fail=root; } else { node * pre=fa->fail; while(pre!=NULL) { if(pre->next[i]!=NULL) { fa->next[i]->fail=pre->next[i]; break; } pre=pre->fail; } if(pre==NULL) fa->next[i]->fail=root; } if(++tail>=10000) tail=0; que[tail]=fa->next[i]; } } } } int query(node *root) { int i,del,ans=0; int len=strlen(t); node *cur=root; for(i=0;i<len;i++) { del=t[i]-31; while(cur!=root&&cur->next[del]==NULL) { cur=cur->fail; } cur=cur->next[del]; if(cur==NULL) cur=root; node *tmp=cur; while(tmp!=root&&tmp->id>0) { res[x++]=tmp->id; tmp=tmp->fail; } } return ans; } int main() { int i,j,n,m,T,num=0; char s[205]; node *root; index=0; root=new node(); scanf("%d",&n); gets(s); for(i=1;i<=n;i++) { gets(s); insert(s,root,i); } build_fail(root); scanf("%d",&m); gets(s); for(i=1;i<=m;i++) { gets(t); x=0; query(root); if(x>0) { num++; printf("web %d:",i); sort(res,res+x); for(j=0;j<x;j++) printf(" %d",res[j]); printf("/n"); } } printf("total: %d/n",num); return 0; }