HDU 2896 AC自動機
題意:給出多組模式串,再給出多組母串,輸出存在於母串中模式串的編號。
#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; }
最後更新:2017-04-03 16:48:50