AC Los automatic machine template Valley P3796

Topic links: https://www.luogu.org/problem/P3796

Meaning of the questions: multiple modes to string and a text string, the string matching requires the highest number is the number, and the number of output patterns of these strings.

Analysis: find the number of matching Obviously, the AC_qurey function look like a little change, but the output of these modes string I lost, only at that time that under Trie on to, to a node can not return to its junction on, would not, in fact it is very simple and obvious, the other with an array of recording position like ah. . . . The dictionary tree node in the end it is only changed one word before the end of the marking, labeling and order of the word.

clean function should be the automaton in the AC initialized, because they do not know how much will be used side, so whenever cnt is increased (ie, there is a new one edge) when we re-initialization

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
typedef long long ll;
#define meminf(a) memset(a,0x3f,sizeof(a))
#define mem0(a) memset(a,0,sizeof(a));
struct result{
    int num,pos;
}ans[200];
bool cmp(const result &a,const result &b){
    if(a.num==b.num) return a.pos<b.pos;
    return a.num> b.num; 
} 
struct Node {
     int Fail; // mismatch pointer Fail 
    int VIS [ 26 is ]; // position of child nodes, i.e. that 26 letters trie 
    int End; // if is tail node is recorded 
} the AC [MAXN];
 char S [ 200 is ] [ 100 ]; // for input pattern string 
char SS [MAXN]; // used to enter a text string 
int CNT = 0 ; // Trie pointer 
void Clean ( int X) { 
    MEM0 (the AC [X] .vis); 
    the AC [X] .end = 0; 
    The AC [X] .fail = 0 ; 
} 
void INSERT ( char * S, int POS) {
     int len = strlen (S);
     int now = 0 ; // trie current pointer 
    for ( int I = 0 ; I <len; I ++ ) {
         // Trie tree no child node 
        IF (the AC [now] .vis [S [I] - ' A ' ] == 0 ) the AC [now] .vis [S [I] - ' A ' ] ++ = CNT, Clean (CNT);
         // plurality of sets of inputs, one need Clear Clear, prior to the need to use this ++ cnt the node
        = the AC now [now] .vis [S [I] - ' A ' ]; 
    } 
    the AC [now] .end = POS; // Mark the node is the end of a word, which is the first flag and a few words 
} 

void get_fail () { 
    Queue < int > que;
     for ( int I = 0 ; I < 26 is ; I ++) { // the fail pointer of the second layer are set to 0 
        IF (the AC [ 0 ] .vis [I]! = 0 ) 
        { 
            the AC [the AC [ 0 .] .vis [I]] Fail = 0 ; 
            que.push (the AC [ 0  ] .vis [I]);
        }             
    } 
    The while (! Que.empty ()) 
    { 
        int U = que.front (); que.pop ();
         for ( int I = 0 ; I < 26 is ; I ++ ) {
             IF (the AC [U] .vis [ I]! = 0 ) {
                 // if the child node of the current node exists, the pointer will fail child node to the child node corresponding to fail at the current node pointer to the node 
                AC [AC [u] .vis [ i .]] Fail = the AC [the AC [U] .fail] .vis [I]; 
                que.push (the AC [U] .vis [I]); 
            } 
            the else the AC [U] .vis [I] = the AC [the AC [U] .fail] .vis [I];
             // else directly to the child node does not exist at a point corresponding to a child node pointer to the current node node fail
         } 
    }
}

void AC_query(char* s){
    int len=strlen(s);
    int now=0;
    for(int i=0;i<len;i++){
        now=AC[now].vis[s[i]-'a'];
        for(int t=now;t!=0;t=AC[t].fail){
            ans[AC[t].end].num++;
        }
    }
}

int main(){
    int n;
    while(~ Scanf ( " % D " , & n-)) 
    { 
    IF (n-== 0 ) BREAK ; 
    CNT = 0 ; 
    Clean ( 0 ); // every time a new edge, remember the previous clear the data 
    for ( int I = . 1 ; I <= n-; I ++ ) { 
        ANS [I] .num = 0 ; 
        ANS [I] .POS = I; 
        Scanf ( " % S " , S [I]); 
        INSERT (S [I ], I); 
    } 
    the AC [ 0 ] .fail = 0 ; // end flag     
    get_fail(); //求出失配指针 
    scanf("%s",ss);
    AC_query(ss); 
    sort(ans+1,ans+1+n,cmp);
    printf("%d\n",ans[1].num);
    for(int i=1;i<=n;i++){
        if(ans[i].num==ans[1].num){
            printf("%s\n",s[ans[i].pos]);
        }
        else break;
    }
    }
    return 0;
} 

 

Guess you like

Origin www.cnblogs.com/qingjiuling/p/11375228.html