hdu 2222 Keywords Search(AC自动机)

来源:互联网 发布:淘宝直通车一天多少钱 编辑:程序博客网 时间:2024/06/08 18:55

第一道AC自动机
在hihocoder的第1036 题“Trie图”,在题目看到了Trie图的讲解,当时看的有一点没明白,然后索性就去搜索AC自动机的讲解
http://blog.csdn.net/niushuai666/article/details/7002823
看的这篇博客的讲解,然后又读了好多遍博主给出的一个例题的代码才看懂AC自动机,例题是:
http://blog.csdn.net/niushuai666/article/details/7002736
然后把例题自己又写了一遍。

#include <cstdio>#include <cstring>struct node{    node *fail;    int cnt;    node *next[26];    node()    {        cnt = 0;        fail = NULL;        memset(next,0,sizeof(next));    }};char keyword[51];char str[1000010];node *que[500010];node *root;int head,tail;void Insert(char* str){    node *p = root;    int len = strlen(str);    int id;    for(int i = 0; i < len; ++i)    {        id = str[i] - 'a';        if(p->next[id] == NULL)            p->next[id] = new node;        p = p->next[id];    }    ++p->cnt;}void buildAc(){    que[tail++] = root;    while(head != tail)    {        node *p = que[head++];        node *temp = NULL;        for(int i = 0; i < 26; ++i)        {            if(p->next[i] != NULL)            {                if(p == root)                    p->next[i]->fail = root;                else                {                    temp = p->fail;                    while(temp != NULL)                    {                        if(temp->next[i] != NULL)                        {                            p->next[i]->fail = temp->next[i];                            break;                        }                        temp = temp->fail;                    }                    if(temp == NULL)                        p->next[i]->fail = root;                }                que[tail++] = p->next[i];            }        }    }}int query(){    int index,result;    node *p = root;    result = 0;    int len = strlen(str);    for(int i = 0; i < len; ++i)    {        index = str[i] - 'a';        while(p->next[index] == NULL && p != root)            p = p->fail;        p = p->next[index];        if(p == NULL)            p = root;        node *temp = p;        while(temp != root && temp->cnt != -1)        {            result += temp->cnt;            temp->cnt = -1;            temp = temp->fail;        }    }    return result;}int main(){    int t,n;    scanf("%d",&t);    while(t--)    {        head = tail = 0;        root = new node;        scanf("%d",&n);        for(int i = 0; i < n; ++i)        {            scanf("%s",keyword);            Insert(keyword);        }        buildAc();        scanf("%s",str);        printf("%d\n",query());    }    return 0;}
0 0
原创粉丝点击