参考博客:点这里
总结:
1.建立trie树
2.构建fail指针
3.查找模式串
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; struct node { node *next[26]; node *fail; int cnt; node() { fail=NULL; cnt=0; memset(next,NULL,sizeof(next)); } }*q[555555]; char a[55],s[1111111]; int n; void trie(char *c,node *root) { node *p=root; int l=strlen(c); for(int i=0;i<l;i++) { int u=c[i]-'a'; if(p->next[u]==NULL) { p->next[u]=new node(); } p=p->next[u]; } p->cnt++; } void buildac(node *root) { int head=0,tail=0; root->fail=NULL; q[tail++]=root; while(head<tail) { node *u=q[head++]; node *p=NULL; for(int i=0;i<26;i++) { if(u->next[i]!=NULL) { if(u==root)u->next[i]->fail=root; else { p=u->fail; while(p!=NULL) { if(p->next[i]!=NULL) { u->next[i]->fail=p->next[i]; break; } p=p->fail; } if(p==NULL)u->next[i]->fail=root; } q[tail++]=u->next[i]; } } } } void query(node *root) { int ans=0; int l=strlen(s); node *p=root; for(int i=0;i<l;i++) { int u=s[i]-'a'; while(p->next[u]==NULL&&p!=root)p=p->fail; if(p->next[u]==NULL)p=root; else p=p->next[u]; node *temp=p; while(temp!=root&&temp->cnt!=-1) { ans+=temp->cnt; temp->cnt=-1; temp=temp->fail; } } printf("%d\n",ans); } int main() { int ca; scanf("%d",&ca); while(ca--) { node *root=new node(); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%s",a); trie(a,root); } scanf("%s",s); buildac(root); query(root); } return 0; }
数组版
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<vector> #include<algorithm> #include<string> #include<cmath> using namespace std; struct node { int fail; int next[26]; int cnt; }t[555555]; char a[55]; char s[1111111]; int q[555555]; int n; int num; void trie(char *c) { int p=0; int l=strlen(c); for(int i=0;i<l;i++) { int u=c[i]-'a'; if(t[p].next[u]==-1) { t[p].next[u]=++num; memset(t[num].next,-1,sizeof(t[num].next)); t[num].cnt=0; } p=t[p].next[u]; } t[p].cnt++; } void buildac() { int fst=0,tail=0; t[0].fail=-1; q[tail++]=0; while(fst<tail) { int u=q[fst++]; for(int i=0;i<26;i++) { if(t[u].next[i]!=-1) { if(u==0)t[t[u].next[i]].fail=0; else { int p=t[u].fail; while(p!=-1) { if(t[p].next[i]!=-1) { t[t[u].next[i]].fail=t[p].next[i]; break; } p=t[p].fail; } if(p==-1)t[t[u].next[i]].fail=0; } q[tail++]=t[u].next[i]; } } } } int count() { int p=0; int ans=0; int l=strlen(s); int u; for(int i=0;i<l;i++) { u=s[i]-'a'; while(t[p].next[u]==-1&&p!=0)p=t[p].fail; p=t[p].next[u]; if(p==-1)p=0; int temp=p; while(temp!=0&&t[temp].cnt!=-1) { if(t[temp].cnt) { ans+=t[temp].cnt; t[temp].cnt=-1; } temp=t[temp].fail; } } return ans; } void init() { num=0; t[0].cnt=0; memset(t[0].next,-1,sizeof(t[0].next)); } int main() { int ca; scanf("%d",&ca); while(ca--) { init(); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%s",a); trie(a); } scanf("%s",s); buildac(); printf("%d\n",count()); } return 0; }