题意:给出多组模式串,再给出多组母串,输出存在于母串中模式串的编号。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int kind = 128; char str[10002],s[202]; int virus[10],vcnt; struct node { node *fail; node *next[kind]; int count;//记录当前前缀是完整单词出现的个数 int flag; node() { fail = NULL; count = 0; memset(next,NULL,sizeof(next)); flag=-1; } }; void insert(char *str,node *root,int id) { node *p=root; int i=0,index; while(str[i]) { index = str[i]; if(p->next[index]==NULL) p->next[index]=new node(); p=p->next[index]; i++; } p->count++,p->flag=id; } //寻找失败指针 void build(node *root) { int i; queue<node *>Q; root->fail = NULL; Q.push(root); while(!Q.empty()) { node *temp = Q.front();//q[head++];//取队首元素 Q.pop(); node *p = NULL; for(i=0; i<kind; i++) { if(temp->next[i]!=NULL)//寻找当前子树的失败指针 { p = temp->fail; while(p!=NULL) { if(p->next[i]!=NULL)//到失败指针 { temp->next[i]->fail = p->next[i]; break; } p = p->fail; } if(p==NULL)//无法获取,当前子树的失败指针为根 temp->next[i]->fail = root; Q.push(temp->next[i]); } } } } //询问str中包含n个关键字中多少种即匹配 void query(node *root) { int i = 0,index,len; len = strlen(str); node *p = root; while(str[i]) { index = str[i]; while(p->next[index]==NULL&&p!=root)//失配 p=p->fail; p=p->next[index]; if(p==NULL)//失配指针为根 p = root; node *temp = p; while(temp!=root&&temp->flag!=-1)//寻找到当前位置为止是否出现病毒关键字 { //if(temp->count!=0) virus[vcnt++]=temp->flag; //temp->count=-1; temp=temp->fail; } i++; } } int main() { int n,m; while(~scanf("%d\n",&n)) { node root; for(int i=1; i<=n; i++) { gets(s); insert(s,&root,i); } build(&root); scanf("%d\n",&m); int tot=0; for(int i=1; i<=m; i++) { gets(str); vcnt=0; query(&root); if(vcnt>0) { tot++; sort(virus,virus+vcnt); printf("web %d:",i); for(int j=0; j<vcnt; j++) printf(" %d",virus[j]); puts(""); } } printf("total: %d\n",tot); } return 0; }