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;
  • 相关阅读:
    剑指Offer-Python(6-10)
    Python对MySQL进行增删查改
    剑指Offer-Python(1-5)
    转载:Python中collections模块
    读取单词文件并查某个单词出现的次数
    Python正则表达式-换行的匹配
    Python爬虫-换行的匹配
    转载:Pycharm的常用快捷键
    Python 正则表达式
    Python的类与对象
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11341430.html
Copyright © 2011-2022 走看看