#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int N=128; struct node { node *fail; node *next[N]; int count; node() { fail=NULL; count=0; memset(next,NULL,sizeof(next)); } }*q[500005]; char key[205],model[10005]; int num[50005]; int head,tail; void insert(char *s,node *root,int ant) { node *p = root; int i = 0,k; int len=strlen(s); for(i = 0 ; i < len ; i ++) { k = s[i]; if(p->next[k] == NULL) p->next[k] = new node(); p = p->next[k]; } p->count=ant; } void build_fail(node *root) { int i; q[tail ++] = root; while(head != tail) { node *temp = q[head ++]; node *p=NULL; for(i = 0 ; i < 128 ; i ++) { if(temp->next[i] != NULL) { if(temp == root) temp->next[i]->fail=root; else { p = temp->fail; //p指向当前结点的fail指针 while(p != NULL) //向根节点回溯,找父节点的fail指针指向的节点下有没有相等的前缀 { if(p->next[i] != NULL) //找到相等的节点 { temp->next[i]->fail = p->next[i]; //将fail指针指向想等的节点 break; } p = p->fail;//p指向自身的fail,如果p为root,p->fail为NULL,则p为NULL } if(p == NULL) //temp的fai指针指向的结点下没有相等的节点,fail指向root temp->next[i]->fail = root; } q[tail ++] = temp->next[i];//下一个节点入队列 } } } } int query(node *root) { int i = 0,j=0,k,len = strlen(model); //int flag = 0; node *p = root; for(i = 0 ; i < len ; i++) { k=model[i]; while(p != root && p->next[k] == NULL) //如果p指向的节点为NULL,p就指向它的fail指针 p = p->fail; p = p->next[k]; p = (p == NULL) ? root : p; //如果p的next[k]为NULL,p就指回root,反之p指向next[k] node *temp = p; while(temp != root) { if(temp->count) { num[j ++] = temp->count; } temp=temp->fail; } } //printf("~~~~~~~~~%d\n",j); return j; } int main() { // freopen("Input.txt","r",stdin); // freopen("Output.txt","w",stdout); int n,m,i,j,k; while(~scanf("%d",&n)) { head=tail=0; node *root = new node(); for(i = 1 ; i <= n ; i++) { scanf("%s",key); insert( key , root , i); } build_fail(root); scanf("%d",&m); int total=0; for(j = 1 ; j <= m; j++) { scanf("%s",model); memset(num,0,sizeof(num)); k=query(root); if(k) { printf("web %d:",j); sort(num,num+k); printf(" %d",num[0]); for(i=1;num[i]!=0;i++) { if(num[i]!=num[i-1]) printf(" %d",num[i]); } printf("\n"); total++; } } printf("total: %d\n",total); } return 0; }