AC自动机

Posted Michael-zhou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机相关的知识,希望对你有一定的参考价值。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <utility>
using std::string;
using std::vector;
using std::pair;
using std::make_pair;
#define CHAR_SET_SIZE 26
#define PATTERN_SIZE 300
#define QUERY_SIZE 3000
#define QSIZE 300000
struct node

    node *fail;
    node *child[CHAR_SET_SIZE];
    int point;
    node()
        fail=NULL;
        for (int i=0;i<CHAR_SET_SIZE;++i) child[i]=NULL;
        point=-1;
    
;
node *Q[QSIZE];
node *Root;
vector <string> Pattern_Collection;
void Init()

    Root=new node;

void Insert(char *s,int num)

    node *p=Root;
    for (char *c=s;*c!='\\0';++c)
    
        int t=(*c)-'a';
        if (p->child[t]==NULL)
        
            p->child[t]=new node;
        
        p=p->child[t];
        if ((*(c+1))=='\\0') p->point=num; 
    

void InputPattern()

    printf("Input number of patterns:");
    fflush(stdout);
    int N;
    scanf("%d",&N);
    char s[PATTERN_SIZE];
    for (int i=1;i<=N;++i)
    
        scanf("%s",s);
        Pattern_Collection.push_back(s);
        Insert(s,Pattern_Collection.size()-1);
    

void BuildFailPoint()

    int Qh=0,Qt=1;
    Q[1]=Root;
    while (Qh<Qt)
    
        node *now=Q[++Qh];
        for (int i=0;i<CHAR_SET_SIZE;++i)
        
            if (now->child[i]!=NULL)
            
                if (now==Root) now->child[i]->fail=Root;
                else
                
                    node *p=now->fail;
                    while (p!=NULL)
                    
                        if (p->child[i]!=NULL)
                        
                            now->child[i]->fail=p->child[i];
                            break;
                        
                        p=p->fail;
                    
                    if (p==NULL) now->child[i]->fail=Root;
                
                Q[++Qt]=now->child[i];
            
        
    

char QueryString[QUERY_SIZE];
vector <pair <int,int> > Query()

    vector <pair <int,int> > Ret;
    int Len=strlen(QueryString);
    node *p=Root;
    for (int i=0;i!=Len;++i)
    
        int index=QueryString[i]-'a';
        while (p->child[index]==NULL && p!=Root) p=p->fail;
        if (p->child[index]==NULL) continue;
        p=p->child[index];
        node *t=p;
        while (t!=Root)
        
            if (t->point!=-1) Ret.push_back(make_pair(t->point,i));
            t=t->fail;
        
    
    return Ret;

void InputQuery()

    printf("Input the query string:\\n");
    scanf("%s",QueryString);
    vector < pair <int,int> > QueryAns=Query();
    for (int i=0;i!=QueryAns.size();++i)
    
        printf("Found pattern \\"%s\\" at %d\\n",
               Pattern_Collection[QueryAns[i].first].c_str(),
               QueryAns[i].second-Pattern_Collection[QueryAns[i].first].size()+1); 
    

int main()

    Init();
    InputPattern();
    BuildFailPoint();
    InputQuery();
    return 0;

以上是关于AC自动机的主要内容,如果未能解决你的问题,请参考以下文章

AC自动机基础

AC自动机详解

AC自动机

AC 自动机

AC自动机详解(附加可持久化AC自动机)

AC自动机