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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值