zoukankan      html  css  js  c++  java
  • HDU 2222 AC自动机 裸题

    题意:

    问母串中出现多少个模式串

    注意ac自动机的节点总数

    #include <stdio.h>  
    #include <string.h>  
    #include <queue>  
    using namespace std;  
    inline int Max(int a,int b){return a>b?a:b;}  
    inline int Min(int a,int b){return a>b?b:a;}  
    int ANS;  
      
      
    #define N 1000010  
    #define maxnode 250001  
    #define sigma_size 26  
      
    struct Trie{  
        int ch[maxnode][sigma_size];  
        int val[maxnode];  
        int last[maxnode];  
        int f[maxnode];  
        int sz;  
        void init(){  
            sz=1;  
            memset(ch,0,sizeof(ch));  
            memset(val, 0, sizeof(val));  
            memset(f,0,sizeof(f));  
            memset(last,0,sizeof(last));  
        }  
        int idx(char c){  
            return c-'a';  
        }  
        void print(int j){  
            if(j){  
                printf("%d: %d
    ", j, val[j]);  
                print(last[j]);  
            }  
        }  
        void Creat(char *s){  
            int u = 0, len = strlen(s);  
            for(int i = 0;i < len;i++){  
                int c = idx(s[i]);  
                if(!ch[u][c])  
                    ch[u][c] = sz++;  
      
                u = ch[u][c];  
            }  
            val[u] ++;  
        }  
        void getFail(){  
            queue<int> q;  
            for(int i = 0; i<sigma_size; i++)  
                if(ch[0][i]) q.push(ch[0][i]);  
      
            while(!q.empty()){  
                int r = q.front(); q.pop();  
                for(int c = 0; c<sigma_size; c++){  
                    int u = ch[r][c];  
                    if(!u)continue;  
                    q.push(u);  
                    int v = f[r];  
                    while(v && ch[v][c] == 0) v = f[v]; //沿失配边走上去 如果失配后有节点 且 其子节点c存在则结束循环  
                    f[u] = ch[v][c];  
                    last[u] = val[f[u]] ? f[u] : last[f[u]];  
                }  
            }  
        }  
        void find(char *T){  
            int len = strlen(T), j = 0;  
            for(int i = 0; i < len; i++){  
                int c = idx(T[i]);  
                while(j && ch[j][c]==0) j = f[j];  
                j = ch[j][c];  
      
                int temp = j;  
                while(temp && val[temp]){  
                    ANS += val[temp];  
                    val[temp] = 0;  
                    temp = f[temp];  
                }  
            }  
        }  
    };  
    Trie ac;  
    char S1[N];  
    int Slen;  
      
    void InputString(){  
        scanf("%s",S1);  
        Slen = strlen(S1);  
        S1[Slen]='';  
    }  
    int main(){  
      
        int T,i,j,n;scanf("%d",&T);  
      
        while(T--){  
            ac.init();  
            scanf("%d",&n);  
            while(n--){  
                scanf("%s",S1);  
                ac.Creat(S1);  
            }  
            ac.getFail();  
            InputString();  
            ANS = 0;  
            ac.find(S1);  
      
            printf("%d
    ",ANS);  
      
        }  
        return 0;  
    }  
    /*  
    1  
    5  
    she  
    he  
    say  
    shr  
    her  
    yasherhs  
      
    ans:  
    3  
    
    */  
    


     

  • 相关阅读:
    二级缓存
    java面试题
    BRD,MRD,PRD文档
    程序做处理时,try..catch和if..else的区别
    关于java中字符串截取
    导出oracle数据库表(备份表)操作命令
    WSDL文件生成java类
    Linux下redis安装(单机版)
    Springboot2.0访问Redis集群
    Spring Cloud Sleuth通过Kafka将链路追踪日志输出到ELK
  • 原文地址:https://www.cnblogs.com/pangblog/p/3358034.html
Copyright © 2011-2022 走看看