Handwritten AC automata, really understand the KMP after the hand-written AC automatic machine or very simple ...
#include <iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<queue>#defineREP (I,A,B) for (int i=a;i<=b;i++)#defineMS0 (a) memset (A,0,sizeof (a))using namespaceStd;typedefLong Longll;Const intmaxn=1000100;Const intinf=1e9+Ten;structtrie{intch[maxn][ -]; intEND[MAXN]; intF[MAXN]; intLAST[MAXN]; intrt,l; intNewNode () {++m; memset (Ch[l],-1,sizeof(Ch[l])); END[L]=0; returnL; } voidinit () {L=-1; RT=NewNode (); } voidInsertChar*s) {intlen=strlen (s); intu=RT; REP (i,0, len-1){ intc=s[i]-'a'; if(ch[u][c]==-1) ch[u][c]=NewNode (); U=Ch[u][c]; } End[u]++; } int Get(intu) {if(!u)return 0; intres=end[u]+Get(Last[u]); End[u]=0; returnRes; } intFindChar*s) {intres=0; intlen=strlen (s); intu=RT; REP (i,0, len-1){ intc=s[i]-'a'; U=Ch[u][c]; if(End[u]) res+=Get(U); Else if(Last[u]) res+=Get(Last[u]); } returnRes; } voidbuild () {Queue<int>Q; REP (c,0, -){ if(~ch[rt][c]) Q.push (Ch[rt][c]), f[ch[rt][c]]=RT; Elsech[rt][c]=RT; } while(!Q.empty ()) { intu=Q.front (); Q.pop (); Last[u]=RT; REP (c,0, -){ if(~ch[u][c]) f[ch[u][c]]=Ch[f[u]][c],q.push (Ch[u][c]); Elsech[u][c]=Ch[f[u]][c]; if(End[f[u]]) last[u]=F[u]; Elselast[u]=Last[f[u]]; } } }}; Trie AC;intN;CharS[MAXN],T[MAXN];intMain () {#ifndef Online_judge freopen ("In.txt","R", stdin); #endif //Online_judge intT;cin>>T; while(t--) {scanf ("%d",&N); Ac.init (); REP (i,1, N) {scanf ("%s", T); Ac.insert (t); } ac.build (); scanf ("%s", s); printf ("%d\n", Ac.find (s)); } return 0;}
View Code
AC Automatic Machine