• AC自动机(转载)


    ac自动机学习博客 

    本来以为是很高级的算法 其实理解以后并不难 只是在字典树的基础上用fail数组标记一下回朔的位置 加速查找 就可以实现多模式串的匹配查找

    模版如下:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<stack>
    #include<bitset>
    #include<cstdlib>
    #include<cmath>
    #include<set>
    #include<list>
    #include<deque>
    #include<map>
    #include<queue>
    #define ll long long int
    using namespace std;
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    int dir[4][2]={1,0 ,0,1 ,-1,0 ,0,-1};
    int dirs[8][2]={1,0 ,0,1 ,-1,0 ,0,-1, -1,-1 ,-1,1 ,1,-1 ,1,1};
    const int inf=0x3f3f3f3f;
    const ll mod=1e9+7;
    struct Trie{
        int trie[500007][26],fail[500007],cntword[500007];
        int sz,root;
        int newnode(){
            for(int i=0;i<26;i++)
                trie[sz][i]=-1;
            cntword[sz++]=0;
            return sz-1;
        }
        void init(){ //初始化 
            sz=0;
            root=newnode();
        }
        void insert(string s){ // 构建字典树 
            int len=s.length();
            int now=root;
            for(int i=0;i<len;i++){
                if(trie[now][s[i]-'a']==-1)
                    trie[now][s[i]-'a']=newnode();
                now=trie[now][s[i]-'a'];
            }
            cntword[now]++;
        }
        void build(){ //构建fail数组 
            queue<int> q;
            fail[root]=root;
            for(int i=0;i<26;i++){
                if(trie[root][i]==-1)
                    trie[root][i]=root;
                else{
                    fail[trie[root][i]]=root;
                    q.push(trie[root][i]);
                }
            }
            while(!q.empty()){
                int now=q.front();
                q.pop();
                for(int i=0;i<26;i++){
                    if(trie[now][i]==-1)
                        trie[now][i]=trie[fail[now]][i];
                    else{
                        fail[trie[now][i]]=trie[fail[now]][i];
                        q.push(trie[now][i]);
                    }
                }
            }
        }
        int query(string s){ //查询操作 
            int len=s.length();
            int now=root;
            int res=0;
            for(int i=0;i<len;i++){
                now=trie[now][s[i]-'a'];
                int temp=now;
                while(temp!=root){
                    res+=cntword[temp];
                    cntword[temp]=0;
                    temp=fail[temp];
                }
            }
            return res;
        }
    };
    Trie ac;
    string s;
    string ans;
    int main(){
        ios::sync_with_stdio(false);return 0;
    }
  • 相关阅读:
    删除指定字符
    Palindromes&nbsp;_easy&nbsp;version
    统计元音
    查找最大元素
    首字母变大写
    Intent加强
    GUI_键盘事件
    GUI_鼠标事件
    GUI_事件监听机制与ActionListener演示
    GUI概述与Frame演示
  • 原文地址:https://www.cnblogs.com/wmj6/p/10828148.html
Copyright © 2020-2023  润新知