hdu2222-AC自动机&模板-Keywords Search

来源:互联网 发布:网络设计方案ppt 编辑:程序博客网 时间:2024/06/08 03:15

http://acm.hdu.edu.cn/showproblem.php?pid=2222
ac自动机的 失配指针不同于 kmp,不是递归算,是用广搜算的。
对很多模式串的处理,是基于字典树。
以后的问题,做题中慢慢遇到吧。

#include <bits/stdc++.h>using namespace std;struct Trie{    int next[500010][26],fail[500010],end[500010];    int root,L;    int newnode()    {        for(int i = 0;i < 26;i++)            next[L][i] = -1;        end[L++] = 0;        return L-1;    }    void init()    {        L = 0;        root = newnode();    }    void insert(char buf[])    {        int len = strlen(buf);        int now = root;        for(int i = 0;i < len;i++)        {            if(next[now][buf[i]-'a'] == -1)                next[now][buf[i]-'a'] = newnode();            now = next[now][buf[i]-'a'];        }        end[now]++;    }    void build()    {  //广搜构造,失配指针        queue<int>Q;        fail[root] = root;        for(int i = 0;i < 26;i++)            if(next[root][i] == -1)                next[root][i] = root;            else            {                fail[next[root][i]] = root;                Q.push(next[root][i]);            }        while( !Q.empty() )        {            int now = Q.front();            Q.pop();            for(int i = 0;i < 26;i++)                if(next[now][i] == -1)                    next[now][i] = next[fail[now]][i];                else                {                    fail[next[now][i]]=next[fail[now]][i];                    Q.push(next[now][i]);                }        }    }    int query(char buf[])    {        int len = strlen(buf);        int now = root;        int res = 0;        for(int i = 0;i < len;i++)        {            now = next[now][buf[i]-'a'];            int temp = now;            while( temp != root )            {                res += end[temp];                end[temp] = 0;                temp = fail[temp];            }        }        return res;    }    void debug()    {        for(int i = 0;i < L;i++)        {            printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);            for(int j = 0;j < 26;j++)                printf("%2d",next[i][j]);            printf("]\n");        }    }};Trie ac;char s[1000006];int main(){    int t,m;     scanf("%d",&t);     while(t--){            ac.init();//初始化           scanf("%d",&m);           getchar();           for(int i=0;i<m;i++){               scanf("%s",s);               ac.insert(s);//插入           }           ac.build();//广搜 构造失配指针。           scanf("%s",s);           printf("%d\n",ac.query(s));     }    return 0;}
原创粉丝点击