http://acm.hdu.edu.cn/showproblem.php?pid=3065
AC自动机
代码:
#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=1005; const int M=505; const int K=26; struct nodeTrie { nodeTrie() { v=0; fail=NULL; for(int i=0;i<K;++i) next[i]=NULL; } int v; nodeTrie *fail; nodeTrie *next[K]; }*root; char s[N][55]; char web[2000005]; int num[N]; void addWord(nodeTrie *p,char *s,int k) { 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)=k; } void init(int n) { root=new nodeTrie; for(int i=1;i<=n;++i) { gets(s[i]); addWord(root,s[i],i); } } 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') { if(s[l]<'A'||s[l]>'Z') {p=root;++l;continue;} 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) ++num[fp->v]; fp=fp->fail; } } return wordCount; } int main() { //freopen("data.in","r",stdin); int n; while(scanf("%d ",&n)!=EOF) { init(n); bfs(root); gets(web); memset(num,0,sizeof(num)); match(root,web); for(int i=1;i<=n;++i) if(num[i]>0) printf("%s: %d\n",s[i],num[i]); } return 0; }