zoukankan      html  css  js  c++  java
  • AC自动机总结

    字典树

    HDU - 1251 统计难题

    模板:

    const int N = 1000;//长度
    
    //初始化 ac.insert();
    //建立字典树 ac.insert();
    //建立 fail,last指针 ac.build();
    //输入文本串进行统计模式串 ac.query(s);
    //统计出现次数 ac.getCount();
    
    
    struct AC_Automata{
        int tire[N][4];
        int val[N];//结尾标记
        int last[N];//last指针
        int fail[N];//fail指针
        int count[N];//对应字符串 id 的出现次数统计
        int tot;
    
        void init(){
            tot = 1;
            val[0] = fail[0] = last[0]  =0;
            memset(tire[0],0,sizeof(tire[0]));
        }
    
        void insert(char *s,int v){
            int len = strlen(s);
            int root = 0;
            for(int i=0;i<len;i++){
                int id = get_id(s[i]);
                if(tire[root][id]==0){
                    tire[root][id] = tot;
                    memset(tire[tot],0,sizeof(tire[tot]));
                    val[tot++] = 0;
                }
                root = tire[root][id];  
            }
            val[root] = 1;  
        }
    
        void build(){
            while(!q.empty()) q.pop();
            last[0] = fail[0] = 0;
            for(int i=0;i<4;i++){
                int root = tire[0][i];
                if(root!=0){
                    fail[root] = 0;
                    last[root] = 0;
                    q.push(root);
                }
            }
            while(!q.empty()){
                int k = q.front();
                q.pop();
                for(int i=0;i<4;i++){
                    int u = tire[k][i];
                    if(u==0){
                        tire[k][i] = tire[fail[k]][i];
                        continue;
                    }
                    q.push(u);
                    fail[u] =tire[fail[k]][i];
                    last[u] = val[fail[u]]?fail[u]:last[fail[u]];
                }
            }
        } 
        void getCount(int i){
            if(val[i]){
                count[val[i]]++;
                get_count(last[i]);
            }
        }
        void query(char *s){
            int len = strlen(s);
            int j=0;
            for(int i=0;i<len;i++){
                int id = get_id(s[i]);
                while(j && tire[j][id]==0){
                    j=fail[j];
                }
                j = tire[j][id];
                if(val[j])
                    getCount(j);
                else if(last[j])
                    getCount(j);
            }
        }
    }ac;
  • 相关阅读:
    三.装饰器函数
    二.函数进阶
    生成器
    一个列表实现__iter__和__next__方法的例子
    可迭代对象和迭代器
    asyncio模块实现线程的嵌套和穿插
    线程的阻塞
    利用collections下的counter实现对列表重复元素的查重
    queue的一些用法
    利用python deque的extend特性实现列表元素查重
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11341430.html
Copyright © 2011-2022 走看看