http://acm.hdu.edu.cn/showproblem.php?pid=2896
AC自动机
ASCII可见字符是从 33~126
代码:
#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=10005; const int M=505; const int K=128; 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]; bool had[M]; 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]]==NULL) p->next[s[i]]=new nodeTrie; p=p->next[s[i]]; } (p->v)=k; } void init(int n) { root=new nodeTrie; for(int i=1;i<=n;++i) { gets(s); addWord(root,s,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') { while(p->next[s[l]]==NULL&&p!=root) p=p->fail; if(p->next[s[l]]!=NULL) p=p->next[s[l]]; ++l; nodeTrie *fp=p; while(fp!=root) { if((fp->v)>0) { if(had[fp->v]==false) {++wordCount;had[fp->v]=true;} } fp=fp->fail; } } return wordCount; } void trieClear(nodeTrie *p) { queue<nodeTrie *>qt; qt.push(p); while(!qt.empty()) { nodeTrie *x=qt.front();qt.pop(); for(int i=0;i<K;++i) if(x->next[i]!=NULL) qt.push(x->next[i]); delete x; } } int main() { //freopen("data.in","r",stdin); int n; while(scanf("%d ",&n)!=EOF) { init(n); bfs(root); int m; scanf("%d ",&m); int total=0; for(int i=1;i<=m;++i) { gets(s); int k; memset(had,false,sizeof(had)); k=match(root,s); if(k>0) { ++total; printf("web %d:",i); for(int j=1;j<=n;++j) if(had[j]) printf(" %d",j); printf("\n"); } } printf("total: %d\n",total); //trieClear(root); } return 0; }