zoukankan      html  css  js  c++  java
  • HDOJ 2222 Keywords Search (AC自动机)

    题意:给n个单词和一个文本,求有多少个单词出现在文本中。

    据说这题是AC自动机的模版题。这题也是我写的第一个AC自动机的题。

    View Code
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    #define LEN 55
    #define N 10010
    int n,node;
    int next[N*LEN][26];
    int cnt[N*LEN];
    int fail[N*LEN];
    void init()
    {
        memset(next[0],0,sizeof(next[0]));
        node=1;
    }
    void add(int cur,int k)
    {
        memset(next[node],0,sizeof(next[node]));
        cnt[node]=0;
        next[cur][k]=node++;
    }
    void insert(char s[])
    {
        int i,k,cur;
        for(i=cur=0;s[i];i++)
        {
            k=s[i]-'a';
            if(!next[cur][k])   add(cur,k);
            cur=next[cur][k];
        }
        cnt[cur]++;
    }
    void build()
    {
        int cur,nxt,k,tmp;
        queue<int> q;
    
        fail[0]=0;
        q.push(0);
    
        while(!q.empty())
        {
            cur=q.front(),q.pop();
            for(k=0;k<26;k++)
            {
                nxt=next[cur][k];
                if(!nxt)    continue;
    
                if(cur==0)  fail[nxt]=0;
    
                else
                {
                    for(tmp=fail[cur];!next[tmp][k] && tmp;tmp=fail[tmp]);
                    fail[nxt]=next[tmp][k];
                }
    
                q.push(nxt);
            }
        }
    }
    int match(char s[])
    {
        int i,k,cur,ans=0;
        for(cur=i=0;s[i];i++)
        {
            k=s[i]-'a';
            for(;next[cur][k]==0 && cur;cur=fail[cur]);
            if(next[cur][k])    cur=next[cur][k];
    
            int tmp=cur;
            while(tmp)
            {
                ans+=cnt[tmp];
                cnt[tmp]=0;
                tmp=fail[tmp];
            }
        }
        return ans;
    }
    int main()
    {
        int k;
        char tmp[LEN];
        char t[1000001];
        scanf("%d",&k);
        while(k--)
        {
            scanf("%d",&n);
            init();
            for(int i=0;i<n;i++)
            {
                scanf("%s",tmp);
                insert(tmp);
            }
            build();
            scanf("%s",t);
            printf("%d\n",match(t));
        }
        return 0;
    }
  • 相关阅读:
    laravel excel 导入
    linux 怎么解压
    mysql分表和表分区详解
    mysql主从复制windows-》linux
    Redis和Memcache的区别
    mysql group by 用法解析(详细)
    [置顶] mysql常用函数
    mysql测试数据库employees一些sql语句
    session入mysql
    session入库
  • 原文地址:https://www.cnblogs.com/algorithms/p/2617130.html
Copyright © 2011-2022 走看看