• 字符串 AC自动机


    AC自动机的板子简单版。

    代码如下。

    #include<bits/stdc++.h>
    #define sc(x) scanf("%d",&x)
    using namespace std;
    const int maxn=1e6+10;
    int n,cnt;
    struct trie{
        int fail,num;
        int ch[30];
        #define fa(x) ac[x].fail
        #define nu(x) ac[x].num
    }ac[maxn];
    inline void insert(string s){
        int len=s.length();
        int now=0;
        for(int i=0;i<len;i++){
            if(!ac[now].ch[s[i]-'a'])
                ac[now].ch[s[i]-'a']=++cnt;
            now=ac[now].ch[s[i]-'a'];
        }
        nu(now)++;
    }
    //bfs
    inline void getfail(){
        queue<int> q;
        for(int i=0;i<=26;i++)
            if(ac[0].ch[i])
                fa(ac[0].ch[i])=0,q.push(ac[0].ch[i]);
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(ac[now].ch[i]){
                    fa(ac[now].ch[i])=ac[fa(now)].ch[i];
                    q.push(ac[now].ch[i]);
                }
                else
                    ac[now].ch[i]=ac[fa(now)].ch[i];
            }
        }
    } 
    inline int ask(string s){
        int len=s.length();
        int now=0,ans=0;
        for(int i=0;i<len;i++){
            now=ac[now].ch[s[i]-'a'];
            for(int j=now;j&&nu(j)!=-1;j=fa(j)){
                ans+=nu(j);
                nu(j)=-1;
            }
        }
        return ans;
    }
    int main()
    {
        sc(n);
        string s;
        for(int i=1;i<=n;i++){
            cin>>s;
            insert(s);
        }
        fa(0)=0;
        getfail();
        cin>>s;
        printf("%d
    ",ask(s));
        return 0;
    }

    AC自动机节点存什么信息比较重要。

    各个题目都不太一样。

    需要个别的分析。

    具体题目见题解。

    加强版:

    #include<bits/stdc++.h>
    using namespace std;
    int n,cnt;
    const int maxn=1e6+10;
    string c[200];
    int en[maxn];
    int ans[300];
    struct acc{
        int fail,ch[26];
        #define fail(x) ac[x].fail
    }ac[maxn];
    
    
    inline void insert(string s,int x){
        int len=s.length();
        int p=0;
        for(int i=0;i<len;i++){
            if(!ac[p].ch[s[i]-'a']) ac[p].ch[s[i]-'a']=++cnt;
            p=ac[p].ch[s[i]-'a'];
        }
        en[p]=x;
    }
    inline void getfail(){
        queue<int> q;
        for(int i=0;i<26;i++)
            if(ac[0].ch[i]) 
                q.push(ac[0].ch[i]),fail(ac[0].ch[i])=0;
        while(q.size()){
            int p=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(ac[p].ch[i]) 
                    fail(ac[p].ch[i])=ac[fail(p)].ch[i],q.push(ac[p].ch[i]);
                else ac[p].ch[i]=ac[fail(p)].ch[i];
            }
        }
    }
    inline void work(string s){
        int len=s.length();
        int now=0;
        for(int i=0;i<len;i++){
            now=ac[now].ch[s[i]-'a'];
            for(int j=now;j;j=fail(j)) ans[en[j]]++;
        }
    }
    
    int main()
    {
        while(scanf("%d",&n)&&n!=0){
            memset(en,0,sizeof(en));
            memset(ans,0,sizeof(ans));
            memset(ac,0,sizeof(ac));
            for(int i=1;i<=n;i++){
                cin>>c[i];
                insert(c[i],i);
            }
            getfail();
            string s;
            cin>>s;
            work(s);
            int now=0;
            for(int i=1;i<=n;i++)
                if(ans[i]>now) now=ans[i]; 
            printf("%d
    ",now);
            for(int i=1;i<=n;i++)
                if(ans[i]==now) cout<<c[i]<<endl;
        }
        // system("pause");
        return 0;
    }
  • 相关阅读:
    2017.3.22上午
    2017.3.21下午
    2017.3.21上午
    git上传到阿里云code
    spring+ibatis整合
    Aop资料整理
    java加密算法之AES小记
    单例的八种写法:推荐静态内部类和枚举
    dubbo入门示例
    自定义注解判空简单示例
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/11144051.html
Copyright © 2020-2023  润新知