After a night of AC automata, I found that I needed to learn trie and KMP ... No, not at all. So he went to learn KMP and trie. Finally the basic understanding of AC automata.
#include <iostream>using namespacestd;structnode{intnext[ -];//the letters that each node can extend to intFail//A mismatch pointer for each node intCount//record the depth of each string that can form a word from the root node voidInit ()//Construction{memset (Next,-1,sizeof(next));//Initialize next to-1, which is not connected to any valueFail =0;//the mismatch pointer is emptyCount =0;//at first, no word was assigned to 0 .}}s[500005];intSind//record the number of the nodeCharstr[ -];//template string, "word"Chardes[1000005];//"article"intq[500005], Qin, qout;//QueuevoidCas_init ()//build root before the entire program{s[0].init ();//Initialize the head node.sind =1;//There is currently one node}voidINS ()//Insert a letter into the book{ intlen = strlen (str);//length of template string intI, J, Ind; for(i = IND =0; i < Len; i++) {J= Str[i]-'a';//find out the number of letters in next if(S[ind].next[j] = =-1)//if it is empty, construct a new, if not empty, then follow the previous start down the structure{s[sind].init ();//Initialize the current nodeS[IND].NEXT[J] = sind++;//Connect to the current node and add Sind to the expansion node} IND= S[ind].next[j];//Traverse down} s[ind].count++;//increase the number of strings on this path from the root node, possibly more than one word on a route}voidMake_fail ()//constructing a mismatch pointer{Qin= Qout =0;//Initialize Queue intI, Ind, Ind_f; for(i =0; I < -; i++) { if(s[0].next[i]! =-1) {Q[qin+ +] = s[0].next[i];//first consider the root node, and the root node is connected to the queue } } while(Qin! =qout) {IND= q[qout++];//Record team first node for(i =0; I < -; i++)//next to traverse the first node of the team { if(S[ind].next[i]! =-1)//If the node next is not empty{Q[qin+ +] = S[ind].next[i];//to queue a son nodeInd_f = S[ind].fail;//the mismatch pointer of a record node points to while(Ind_f >0&& S[ind_f].next[i] = =-1)//when the mismatch pointer is not root, it loops until the son who finds a node is the I value or to rootInd_f =S[ind_f].fail; if(S[ind_f].next[i]! =-1)//If the current node has a son, record the backup.Ind_f =S[ind_f].next[i]; S[s[ind].next[i]].fail= Ind_f;//causes the mismatch pointer of the current node to point to the search construct of the node that was just logged to complete the mismatch pointer. } } }}intfd () {intCT =0;//record "Number of words" intDI, I, Ind, p;//di is a pointer to the article, and the IND is a pointer to a mismatch node (that is, a self-matching pointer in the trie tree) similar to temp in the next array in KMP intLen = strlen (des);//"Length of article" for(di = IND =0; Di < Len; di++) {i= Des[di]-'a'; while(Ind >0&& S[ind].next[i] = =-1)//when the IND pointer is not root and the son that cannot find the node is I, keep looking down (i.e. the while loop in KMP)IND = S[ind].fail;//always looking for a mismatch pointer if(S[ind].next[i]! =-1)//found a suitable mismatch pointer{IND= S[ind].next[i];//point to the Son node, update the value of the IND for the next matchP= IND;//use p to temporarily replace IND while(P >0&& S[p].count! =-1)//p > 0 means not yet root,count! =-1 indicates that there are words before the pointer{CT+ = S[p].count;//plus the number of wordsS[p].count =-1;//do not repeat calculations, it is important to note herep = s[p].fail;//always looking for a mismatch pointer } } } returnCt//returns the number of words}intMain () {intcas, n; scanf ("%d", &CAs); while(cas--&& scanf ("%d", &N)) {gets (str); Cas_init ();//initializing the trie tree while(n--&&gets (str)) ins ();//Constructing the trie treeMake_fail ();//constructing a mismatch pointergets (DES); printf ("%d\n", FD ()); } return 0;}
AC Automata Learning Notes