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


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

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

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

    #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
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    The library 'hostpolicy.dll' required to execute the application was not found in
    矩阵乘法
    2019-11-1
    四边形不等式的应用
    2019-10-30
    2019-10-29
    差分与前缀和
    平衡树SPLAY
    可爱的树链剖分(染色)
    cable tv network
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3892548.html
Copyright © 2020-2023  润新知