AC自动机2

AC自动机

给N个模式串,求文本串中出现次数最多的模式串出现次数。

#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
#define maxm 28
struct AC
{
    int trieN;
    int ch[maxn][maxm];
    int val[maxn];
    int fail[maxn];
    int s[maxn];
    int tim[maxn];
    void init()
    {
        trieN=-1;
        newnod();
    }
    int newnod()
    {
        memset(ch[++trieN],0,sizeof ch[0]);
        val[trieN]=fail[trieN]=0;
        tim[trieN]=s[trieN]=0;
        return trieN;
    }
    void insert(const string & str,int k)
    {
        int cur=0;
        for(int i=0; i<str.size(); i++)
        {
            int d=str[i]-'a';
            if(!ch[cur][d])
            {
                ch[cur][d]=newnod();
            }
            cur=ch[cur][d];
        }
        val[cur]++;
        s[cur]=k;
    }
    void build()
    {
        queue<int> q;
        for(int i=0; i<maxm; i++)
        {
            if(ch[0][i])
            {
                q.push(ch[0][i]);
            }
        }
        while(!q.empty())
        {
            int cur=q.front();
            q.pop();
            for(int i=0; i<maxm; i++)
            {
                if(ch[cur][i])
                {
                    fail[ch[cur][i]]=ch[fail[cur]][i];
                    q.push(ch[cur][i]);
                }
                else
                {
                    ch[cur][i]=ch[fail[cur]][i];
                }
            }
        }
    }
    vector<int>ans;
    int man=0;
    void query(const string & str)
    {
        ans.clear();
        man=0;
        int res=0,cur=0;
        for(int i=0; str[i]; i++)
        {
            int d=str[i]-'a';
            cur=ch[cur][d];
            int tmp=cur;
            // int si=0;
            //cout<<tmp<<'\n';
            while(tmp&&val[tmp]>=0)
            {
                res=val[tmp];
                if(val[tmp])
                {
                    tim[tmp]++;
                    if(tim[tmp]>man)
                    {
                        man=tim[tmp];
                        ans.clear();
                        for(int _i=0; _i<res; _i++)
                            ans.push_back(s[tmp]);
                    }
                    else if(man==tim[tmp])
                    {
                        for(int _i=0; _i<res; _i++)
                            ans.push_back(s[tmp]);
                    }
                }
                //val[tmp]=-1;
                tmp=fail[tmp];
            }



        }
    }
} ac;
string A[maxn];
int main()
{
    string s;
    int n;
    while(scanf("%d",&n))
    {
        ac.init();
        if(n==0)break;
        for(int i=0; i<n; i++)
        {
            cin>>A[i];
            ac.insert(A[i],i);
        }
        ac.build();
        cin>>s;
        ac.query(s);
        cout<<ac.man<<'\n';
        sort(ac.ans.begin(),ac.ans.end());
        for(int i=0; i<ac.ans.size(); i++)
        {
            cout<<A[ac.ans[i]]<<'\n';
        }
    }
}

 

posted @ 2019-08-08 09:28  liulex  阅读(136)  评论(0编辑  收藏  举报