标签:ring ac自动机 auto eve tomat count scanf %s show
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cmath> #include <map> #include <set> using namespace std; #define N 10000005 const int kind=26; int head,tail; char str[N]; struct node { node *fail; //失败指针 node *next[kind];//Trie每个节点的子节点 int count; //是否为该单词的最后一个节点 node() { fail=NULL; count=0; memset(next,NULL,sizeof(next)); } }*q[500001]; //bfs构造失败指针 void insert(char *str,node *root) { node *p=root; int i=0,index; while(str[i]) { index=str[i]-‘a‘; if(p->next[index]==NULL) p->next[index]=new node(); p=p->next[index]; i++; } p->count++; //标记单词结尾 有一个单词-- } void build_ac_automation(node *root) //失败指针建立 { int i; root->fail=NULL; q[head++]=root; //根入队列 while(head!=tail) { node *temp=q[tail++]; node *p=NULL; for(i=0; i<26; i++) { if(temp->next[i]!=NULL) { if(temp==root) temp->next[i]->fail=root; else { 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[head++]=temp->next[i]; } } } } int query(node *root) //多模式串匹配 { int i=0,cnt=0,index,len=strlen(str); node *p=root; while(str[i]) { index=str[i]-‘a‘; while(p->next[index]==NULL && p!=root) p=p->fail; p=p->next[index]; p=(p==NULL)?root:p; node *temp=p; while(temp!=root && temp->count!=-1) { cnt+=temp->count; temp->count=-1; temp=temp->fail; } i++; } return cnt; } int main() { int T,n,m,k; scanf("%d",&T); while(T--) { scanf("%d",&n); node *root=NULL; root=new node(); for(int i=1;i<=n;i++) { scanf("%s",str); insert(str,root); } //建立tree树 build_ac_automation(root); //建立失败指针 scanf("%s",str); int ans=query(root); // 多模式匹配 delete(root); printf("%d\n",ans); } }
标签:ring ac自动机 auto eve tomat count scanf %s show
原文地址:https://www.cnblogs.com/ww123/p/9568436.html