[模板]AC自动机(2)

题目描述

求出现在文本串中最多的模式串

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1000005

int N;
char s[155][100];
char T[MAXN];
int len;

struct queue{
    int que[MAXN];int head,tail;
    inline void clear(){head = 1;tail = 0;}
    inline void pop(){head++;}
    inline int front(){return que[head];}
    inline void push(int x){que[++tail]=x;}
    inline bool empty(){return head>tail;}
}q;
struct Node{
    int val,num;
};
struct Auto{
    int trie[26][MAXN];Node rec[MAXN];int fail[MAXN];int tot;int count[MAXN];
    inline void clear(){
        std::memset(trie,0,sizeof(trie));
        std::memset(rec,0,sizeof(rec));
        std::memset(count,0,sizeof(count));
        tot = 0;
    }
    inline void ins(int x){
        int _next = 0;len = std::strlen(s[x]);
        for(register int i=0;i<len;++i){
            int c = s[x][i]-'a';
            if(!trie[c][_next])trie[c][_next]=++tot;
            _next = trie[c][_next];
        }
        rec[_next].val++;
        rec[_next].num = x;
    }
    inline void make_fail(){
        for(register int i=0;i<26;++i){
            if(trie[i][0]){
                q.push(trie[i][0]);
                fail[trie[i][0]] = 0;
            }
        }
        while(!q.empty()){
            int u = q.front();q.pop();
            for(register int i=0;i<26;++i){
                if(trie[i][u]){
                    q.push(trie[i][u]);
                    fail[trie[i][u]] = trie[i][fail[u]];
                }
                else trie[i][u] = trie[i][fail[u]];
            }
        }
    }
    inline void find(){
        int _next = 0;len = std::strlen(T);
        for(register int i=0;i<len;++i){
            _next = trie[T[i]-'a'][_next];
            for(register int j=_next;j;j=fail[j]){
                if(rec[j].val)count[rec[j].num]++;
            }
        }
    }
}AC;

int ans[MAXN];

int main(){

    while((scanf("%d\n",&N))&&N>0){
        AC.clear();
        q.clear();
        for(register int i=1;i<=N;++i){
            scanf("%s",s[i]);
            AC.ins(i);
        }
        AC.make_fail();
        scanf("%s",T);
        AC.find();
        
        int maxx = 0;
        int pos = 0;
        for(register int i=1;i<=N;++i){
            if(maxx<AC.count[i]){
                maxx = AC.count[i];
                ans[1]=i;
                pos = 1;
            }
            else if(maxx==AC.count[i])ans[++pos] = i;
        }
        printf("%d\n",maxx);
        for(register int i=1;i<=pos;++i)puts(s[ans[i]]);
    }
    return 0;
}
posted @ 2018-08-23 13:45  Neworld1111  阅读(121)  评论(0编辑  收藏  举报