Luogu P3808 AC自动机简单版___AC自动机

题目大意:

给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。

subtask1[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6,n=1;
subtask2[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6;

题解:

一个AC自动机的模版,
AC自动机=trie树+fail边,
可以在一个串中实现高效的多模匹配
对于fail边的解释,还是需要画图去多意会..
学习链接;
http://blog.csdn.net/creatorx/article/details/71100840
http://blog.csdn.net/u013371163/article/details/60469534

代码:

#include
#define N 500010

using namespace std;
queue <int> Q;

struct Aho_Corasick_Automaton
{
int num,next[N][26],fail[N],end[N];

void insert(char *s)
    {
        int len=strlen(s);
        int u=0;
        for (int i=0; i<len; i++)
        {
             int v=s[i]-'a';
             if (!next[u][v]) next[u][v]=++num;
             u=next[u][v];
        }
        end[u]++;
    }

void build()
    {
        fail[0]=0;
        for (int i=0; i<26; i++)
            if (next[0][i]) 
                 {
                          fail[next[0][i]]=0;
                          Q.push(next[0][i]);
                 }      

        while (!Q.empty())
        {
            int now=Q.front();
            Q.pop();
            for (int i=0; i<26; i++)
                 if (!next[now][i]) 
                      next[now][i]=next[fail[now]][i];
                      else {
                               fail[next[now][i]]=next[fail[now]][i];
                               Q.push(next[now][i]);
                           }
        }
    }

int query(char *s)
    {
        int len=strlen(s);
        int now=0,rp=0;
        for (int i=0; i<len; i++)
        {
            int v=s[i]-'a';
            now=next[now][v];
            int u=now;
            while (u!=0 && end[u]!=-1)
            {
                   rp=rp+end[u];
                   end[u]=-1;
                   u=fail[u];
            }               
        }
        return rp;
    }
}AC;

int n;
char s[1000005];

int main()
{
        scanf("%d",&n);

        for (int i=1; i<=n; i++)
        {
             scanf("%s",s);
             AC.insert(s);
        }

        AC.build();
        scanf("%s",s);
        printf("%d\n",AC.query(s));
        return 0;
}

你可能感兴趣的:(C++,AC自动机)