关闭

hdu 2222 Keywords Search (AC自动机)

203人阅读 评论(0) 收藏 举报
分类:
//可能有重复单词
# include <stdio.h>
# include <queue>
# include <string.h>
# include <algorithm>
using namespace std;
char str[110],a[1000010];
# define kind 26
struct node
{
    node *fail;
    node *next[kind];
    int cnt;//从根到此处是否是关键字,并且记录是多少个关键字的结尾
    node()
    {
        fail=NULL;
        cnt=0;
        for(int i=0;i<26;i++)
            next[i]=NULL;
      //  memset(next,0,sizeof(next));
    }

};
queue<node*>qq;
void Buildtree(node *root ,int index)
{
    node *p=root;
    int i=0,id;
    while(str[i])
    {
        id=str[i]-'a';
        if(p->next[id]==NULL)
            p->next[id]=new node();
        p=p->next[id];
        i++;
    }
    (p->cnt)++;///记录是多少个关键字的结尾
}
void bfs(node *root)
{
    while(!qq.empty())
        qq.pop();
    root->fail=NULL;
    qq.push(root);
    root->fail=NULL;
    node *tmp,*p;
    while(!qq.empty())
    {
        tmp=qq.front();
        qq.pop();
        p=NULL;
        for(int i=0;i<kind;i++)
        {
            if(tmp->next[i]!=NULL)
            {
                p=tmp->fail;
                while(p&&!p->next[i])
                    p=p->fail;
                if(!p)
                    tmp->next[i]->fail=root;
                else
                    tmp->next[i]->fail=p->next[i];
                qq.push(tmp->next[i]);
            }
        }
    }
}
int has[10010];
int Ac_run(node *root)
{
    int i=0,ans=0,id;
    node *p=root;
    while(a[i])
    {
        id=a[i]-'a';
        while(!p->next[id]&&p!=root)//跳转失败指针
            p=p->fail;
        p=p->next[id];
        if(!p)
            p=root;
        node *tmp=p;//p不动,temp计算后缀串
        while(tmp!=root&&tmp->cnt!=-1)
        {

                ans+=tmp->cnt;
                tmp->cnt=-1;///
               // has[tmp->cnt]=1;
                tmp=tmp->fail;
        }
        i++;

    }
    return ans;
}
int main()
{
    int t,n;
    while(~scanf("%d",&t))
    {
        while(t--)
        {
            node *root=new node();
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
            {
                scanf("%s",str);
                Buildtree(root,i);
            }
            bfs(root);
         //   memset(has,0,sizeof(has));
            scanf("%s",a);
            printf("%d\n",Ac_run(root));

        }
    }
    return 0;
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:102984次
    • 积分:3204
    • 等级:
    • 排名:第10599名
    • 原创:215篇
    • 转载:19篇
    • 译文:0篇
    • 评论:14条
    最新评论