码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2222 最简单的AC自动机套模板应用

时间:2014-08-05 18:39:09      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   for   art   

HDU 2222 题意:给出N(N<=10,000)个单词,每个单词长度不超过50。再给出一个字符串S,字符串长度不超过1,000,000。问有多少个单词出现在了字符串S中。(单词可能重复,单词在S中允许重叠)

我们在val[]数组中记录重复的个数

因为在主串对他进行匹配时,匹配到一次后这个重复次数就不应该继续添加了,所以在query中val[]要对它进行清零操作

bubuko.com,布布扣
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 500005
char str[1000005];
struct AC{
    int ch[N][26],fail[N],val[N],last[N],tmp,root;
    int newnode(){
        val[tmp]=0;
        memset(ch[tmp],0,sizeof(ch[tmp]));
        return tmp++;
    }
    void init(){
        tmp=0;
        root=newnode();
    }
    void add(char *s){
        int len=strlen(s);
        int now=root;
        for(int i=0;i<len;i++){
            int &k=ch[now][s[i]-a];
            if(!k) k=newnode();
            now=k;
        }
        val[now]++;
    }
    void get_fail(){
        fail[root]=root;
        queue<int> q;
        for(int i=0;i<26;i++){
            int v=ch[root][i];
            if(v)
                fail[v]=last[v]=0,q.push(v);
        }
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                int v=ch[now][i];
                if(!v) ch[now][i]=ch[fail[now]][i];
                else{
                    fail[v]=ch[fail[now]][i];
                    last[v]=val[fail[v]]?fail[v]:last[fail[v]];
                    q.push(v);
                }
            }
        }
    }
    int query(char *str){
        int len=strlen(str);
        int now=root,ret=0;
        for(int i=0;i<len;i++){
            now=ch[now][str[i]-a];
            int k=now;
            while(k!=root&&val[k]){//这是要循环到找到fail值为root的时候或者找到匹配的字符串的时候,否则一直向前找fail值,
                ret+=val[k];
                val[k]=0;
                k=last[k];
            }
        }
        return ret;
    }
}ac;
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--){
        ac.init();
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%s",str);
            ac.add(str);
        }
        ac.get_fail();
        scanf("%s",str);
        int ans=ac.query(str);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

HDU 2222 最简单的AC自动机套模板应用,布布扣,bubuko.com

HDU 2222 最简单的AC自动机套模板应用

标签:style   blog   http   color   os   io   for   art   

原文地址:http://www.cnblogs.com/CSU3901130321/p/3892548.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!