HDOJ_2222 AC自动机

这个题网上有很多讲解,感觉在看这个题之前最好先去看看KMP ,不然看再多的讲解,可能也不能理解构造失败指针的意义是什么。在KMP中NEXT的作用是党不匹配时指针后移,而这个后移量则是通过 NEXT 来控制的,这个题里面 构造 失败指针的意义 和NEXT的作用一样,就是前后移动指针的。这个懂了,再看看别人的图示,就会明白构造的过程,其中 我理解的是用 广度优先 遍历的。大家可以看看这个文章http://www.cppblog.com/mythit/archive/2009/04/21/80633.html 里面讲解的很详细。

代码:

#include<stdio.h>

#include<queue>

using namespace std;

typedef struct node

{

    int count;

    node *fail;

    node *next[26];

}node;

node *h;

void insert(char *key)

{

    int i;

    node *p;

    char *q;

    p=h;

    q=key;

    while(*q)

    {

        if(p->next[*q-'a']==NULL)

        {

            p->next[*q-'a']=(node*)malloc(sizeof(node));

            p->next[*q-'a']->count=0;

            p->next[*q-'a']->fail=NULL;

            for(i=0;i<26;++i)

                p->next[*q-'a']->next[i]=NULL;

        }

        p=p->next[*q-'a'];

        q++;

    }

    p->count++;

}

void makefail()

{

    int i;

    node *fa,*so,*an;

    queue<node*>qu;

    qu.push(h);

    while(!qu.empty())

    {

        fa=qu.front();

        qu.pop();

        for(i=0;i<26;++i)

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

            {

                if(fa==h)

                    fa->next[i]->fail=h;

                else

                {

                    so=fa->next[i];

                    an=fa->fail;

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

                        an=an->fail;

                    if(an==NULL)

                        so->fail=h;

                    else

                        so->fail=an->next[i];

                }

                qu.push(fa->next[i]);

            }

    }

}

int find(char *des)

{

    int sum=0,at,i;

    node *p,*q;

    p=h;

    i=0;

    while(des[i])

    {

        at=des[i]-'a';

        while(p->next[at]==NULL&&p!=h)

            p=p->fail;

        p=p->next[at];

        if(p==NULL)

            p=h;

        q=p;

        while(q!=h&&q->count)

        {

            sum+=q->count;

            q->count=0;

            q=q->fail;

        }

        i++;

    }

    return sum;

}

int main()

{

    int T,i,n;

    char str[55],des[1000005];

    h=(node*)malloc(sizeof(node));

    scanf("%d",&T);

    while(T--)

    {

        h->fail=NULL;

        for(i=0;i<26;++i)

            h->next[i]=NULL;

        scanf("%d",&n);

        while(n--)

        {

            scanf("%s",str);

            insert(str);

        }

        makefail();

        scanf("%s",des);

        printf("%d\n",find(des));

    }

    return 0;

}

 

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