zoukankan      html  css  js  c++  java
  • AC自动机 P3808 P3796

    第一次写AC自动机##

    简单版的这道题可以在进行匹配的时候剪一下枝,应为之前比配过了,不用在匹配了。

    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    const int MAXN=1e6+10;
    queue<int> que;
    
    struct AC{
        int tr[MAXN][26],fail[MAXN],val[MAXN],tot;
    
        void insert(char *s){
            int n=strlen(s+1),p=0;
            for(int i=1;i<=n;i++){
                if(!tr[p][s[i]-'a'])
                    tr[p][s[i]-'a']=++tot;
                p=tr[p][s[i]-'a'];
            }
            val[p]++;
        }
    
        void getfail(){
            while(!que.empty()) que.pop();
            for(int i=0;i<26;i++)
                if(tr[0][i])
                    que.push(tr[0][i]);
            while(!que.empty()){
                int u=que.front();que.pop();
                for(int i=0;i<26;i++)
                    if(tr[u][i]) fail[tr[u][i]]=tr[fail[u]][i],que.push(tr[u][i]);
                    else tr[u][i]=tr[fail[u]][i];
            }
            // for(int i=0;i<=tot;i++) cout<<fail[i]<<" ";cout<<endl;
            // for(int i=0;i<=tot;i++) cout<<val[i]<<" ";cout<<endl;
        }
    
        int ask(char *s){
            int n=strlen(s+1),p=0,ans=0;
            for(int i=1;i<=n;i++){
                p=tr[p][s[i]-'a'];
                for(int t=p;t&&val[t]!=-1;t=fail[t])
                    ans+=val[t],val[t]=-1;
            }
            return ans;
        }
    }ac;
    
    int n;
    char s[MAXN];
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s+1);
            ac.insert(s);
        }
        ac.getfail();
        scanf("%s",s+1);
        int ans=ac.ask(s);
        printf("%d
    ",ans);
        return 0;
    }
    

    加强版的题,就不能剪枝了,因为要求出每个模式串出现的次数。

    可以在 (trie) 的末节点上记录该串的 (id) 然后每次匹配到就给它++就行了。

    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    const int MAXN=1e6+10;
    queue<int> que;
    int cnt[160],ans,n;
    char s[160][100],str[MAXN];
    
    struct AC{
        int tr[16000][26],fail[MAXN],val[MAXN],tot;
    
        void init(){
            memset(cnt,0,sizeof(cnt));
            memset(tr,0,sizeof(tr));
            memset(fail,0,sizeof(fail));
            memset(val,0,sizeof(val));
            tot=0;
            ans=0;
        }
    
        void insert(char *s,int id){
            int n=strlen(s+1),p=0;
            for(int i=1;i<=n;i++){
                if(!tr[p][s[i]-'a']) tr[p][s[i]-'a']=++tot;
                p=tr[p][s[i]-'a'];
            }
            val[p]=id;
        }
    
        void getfail(){
            while(!que.empty()) que.pop();
            for(int i=0;i<26;i++)
                if(tr[0][i]) que.push(tr[0][i]);
            while(!que.empty()){
                int u=que.front();que.pop();
                for(int i=0;i<26;i++)
                    if(tr[u][i]) fail[tr[u][i]]=tr[fail[u]][i],que.push(tr[u][i]);
                    else tr[u][i]=tr[fail[u]][i];
            }
        }
    
        void ask(char *s){
            int n=strlen(s+1),p=0;
            for(int i=1;i<=n;i++){
                p=tr[p][s[i]-'a'];
                for(int t=p;t;t=fail[t])
                    if(val[t]) cnt[val[t]]++,ans=max(ans,cnt[val[t]]);
            }
        }
    }ac;
    
    int main(){
        while(~scanf("%d",&n)){
            if(!n) break;
            ac.init();
            for(int i=1;i<=n;i++) 
                scanf("%s",s[i]+1),
                ac.insert(s[i],i);
            ac.getfail();
            scanf("%s",str+1);
            ac.ask(str);
            printf("%d
    ",ans);
            for(int i=1;i<=n;i++) if(cnt[i]==ans) printf("%s
    ",s[i]+1);
        }
        return 0;
    }
    
  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    基于分布式锁解决定时任务重复问题
    基于Redis的Setnx实现分布式锁
    基于数据库悲观锁的分布式锁
    使用锁解决电商中的超卖
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/11771700.html
Copyright © 2011-2022 走看看