hdu 2222 Keywords Search

http://acm.hdu.edu.cn/showproblem.php?pid=2222

第一个AC自动机

AC自动机就是在trie上进行kmp

需要三个步骤

1,建立trie

2,求fail指针

3,匹配

代码:

#include<iostream>

#include<cmath>

#include<cstdio>

#include<string>

#include<cstring>

#include<vector>

#include<stack>

#include<queue>

#include<set>

#include<map>

#include<algorithm>



#define LL long long



using namespace std;



const int INF=0x3f3f3f3f;

const int N=1000005;

const int K=26;

struct nodeTrie

{

    nodeTrie()

    {

        v=0;

        fail=NULL;

        for(int i=0;i<K;++i)

        next[i]=NULL;

    }

    int v;

    struct nodeTrie *fail;

    struct nodeTrie *next[K];

}*root;

char s[N];

void addWord(nodeTrie *p,char *s)

{

    if(s[0]=='\0') return ;

    for(int i=0;s[i]!='\0';++i)

    {

        if(p->next[s[i]-'a']==NULL)

        p->next[s[i]-'a']=new nodeTrie;

        p=p->next[s[i]-'a'];

    }

    ++(p->v);

}

void init(int n)

{

    root=new nodeTrie;

    while(n--)

    {

        gets(s);

        addWord(root,s);

    }

}

void bfs(nodeTrie *p)

{

    p->fail=root;

    queue<nodeTrie *>qt;

    qt.push(p);

    while(!qt.empty())

    {

        nodeTrie *y;

        nodeTrie *x=qt.front();qt.pop();

        for(int i=0;i<K;++i)

        if(x->next[i]!=NULL)

        {

            qt.push(x->next[i]);

            if(x==root)

            {x->next[i]->fail=root;continue;}

            y=x->fail;

            while(y!=root&&y->next[i]==NULL)

            y=y->fail;

            if(y->next[i]!=NULL)

            x->next[i]->fail=y->next[i];

            else

            x->next[i]->fail=root;

        }

    }

}

int match(nodeTrie *p,char *s)

{

    int wordCount=0;

    int l=0;

    while(s[l]!='\0')

    {

        while(p->next[s[l]-'a']==NULL&&p!=root)

        p=p->fail;

        if(p->next[s[l]-'a']!=NULL)

        p=p->next[s[l]-'a'];

        ++l;

        nodeTrie *fp=p;

        while(fp!=root)

        {

            if((fp->v)>0) {wordCount+=(fp->v);fp->v=0;}

            fp=fp->fail;

        }

    }

    return wordCount;

}

int main()

{

    //freopen("data.in","r",stdin);

    int T;

    scanf("%d",&T);

    while(T--)

    {

        int n;

        scanf("%d ",&n);

        init(n);

        bfs(root);

        gets(s);

        printf("%d\n",match(root,s));

    }

    return 0;

}

  

 

你可能感兴趣的:(search)