http://acm.hdu.edu.cn/showproblem.php?pid=2222
第一个AC自动机
AC自动机就是在trie上进行kmp
需要三个步骤
1,建立trie
2,求fail指针
3,匹配
代码:
#include<iostream> #include<cmath> #include<cstdio> #include<string> #include<cstring> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<algorithm> #define LL long long using namespace std; const int INF=0x3f3f3f3f; const int N=1000005; const int K=26; struct nodeTrie { nodeTrie() { v=0; fail=NULL; for(int i=0;i<K;++i) next[i]=NULL; } int v; struct nodeTrie *fail; struct nodeTrie *next[K]; }*root; char s[N]; void addWord(nodeTrie *p,char *s) { if(s[0]=='\0') return ; for(int i=0;s[i]!='\0';++i) { if(p->next[s[i]-'a']==NULL) p->next[s[i]-'a']=new nodeTrie; p=p->next[s[i]-'a']; } ++(p->v); } void init(int n) { root=new nodeTrie; while(n--) { gets(s); addWord(root,s); } } void bfs(nodeTrie *p) { p->fail=root; queue<nodeTrie *>qt; qt.push(p); while(!qt.empty()) { nodeTrie *y; nodeTrie *x=qt.front();qt.pop(); for(int i=0;i<K;++i) if(x->next[i]!=NULL) { qt.push(x->next[i]); if(x==root) {x->next[i]->fail=root;continue;} y=x->fail; while(y!=root&&y->next[i]==NULL) y=y->fail; if(y->next[i]!=NULL) x->next[i]->fail=y->next[i]; else x->next[i]->fail=root; } } } int match(nodeTrie *p,char *s) { int wordCount=0; int l=0; while(s[l]!='\0') { while(p->next[s[l]-'a']==NULL&&p!=root) p=p->fail; if(p->next[s[l]-'a']!=NULL) p=p->next[s[l]-'a']; ++l; nodeTrie *fp=p; while(fp!=root) { if((fp->v)>0) {wordCount+=(fp->v);fp->v=0;} fp=fp->fail; } } return wordCount; } int main() { //freopen("data.in","r",stdin); int T; scanf("%d",&T); while(T--) { int n; scanf("%d ",&n); init(n); bfs(root); gets(s); printf("%d\n",match(root,s)); } return 0; }