• HDU2222 Keywords Search [AC自动机]


      AC自动机的模版题,应该是很多人的AC自动机处女作吧。。

      在斌牛的讲解下,总算是对AC自动机了解了个大概,这里采用了AC自动机和Trie图两种写法,据说后者在AC自动机DP中用的比较多,应该很快就会做到了。。。两者差不多,Trie图利用失败指针来建图,据说AC自动机到Trie图就是转化成了确定性有穷自动机。

      贴一下两种写法的代码,当模版了。

     AC自动机:

    #include <string.h>
    #include <stdio.h>
    #include <queue>
    #define MAXS 500010
    
    int cas,n;
    char s[55],find[1000005];
    int next[MAXS][26],pos,tot[MAXS],fail[MAXS];
    int newnode(){
        memset(next[pos],0,sizeof next[pos]);
        tot[pos]=fail[pos]=0;
        return pos++;
    }
    void insert(char *s){
        int len=strlen(s);
        int p=0;
        for(int i=0;i<len;i++){
            int k=s[i]-'a';
            p=next[p][k]?next[p][k]:next[p][k]=newnode();
        }
        ++tot[p];
    }
    void makefail(){
        std::queue<int> q;
        q.push(0);
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=0;i<26;i++){
                int v=next[u][i];
                if(v==0)continue;
                q.push(v);
                if(u==0)continue;
                fail[v]=next[0][i];
                for(int f=fail[u];f!=0;f=fail[f]){
                    if(next[f][i]){
                        fail[v]=next[f][i];
                        break;
                    }
                }
            }
        }
    }
    int makeans(char *s){
        int ans=0;
        for(int i=0,p=0;s[i];i++){
            int k=s[i]-'a';
            while(p>0&&!next[p][k])p=fail[p];
            p=next[p][k];
            for(int t=p;t!=0;t=fail[t]){
                if(tot[t]>=0){
                    ans+=tot[t];
                    tot[t]=-1;
                }else break;
            }
        }
        return ans;
    }
    int main(){
    freopen("test.in","r",stdin);
        scanf("%d",&cas);
        for(int ca=1;ca<=cas;ca++){
            scanf("%d",&n);
            pos=0;newnode();
            for(int i=1;i<=n;i++){
                scanf("%s",s);
                insert(s);
            }
            makefail();
            scanf("%s",find);
            int x=makeans(find);
            printf("%d\n",x);
        }
        return 0;
    }

    Trie图:

    #include <string.h>
    #include <stdio.h>
    #include <queue>
    #define MAXS 500010
    
    int cas,n;
    char s[55],find[1000005];
    int next[MAXS][26],pos,tot[MAXS],fail[MAXS];
    int newnode(){
        memset(next[pos],0,sizeof next[pos]);
        tot[pos]=fail[pos]=0;
        return pos++;
    }
    void insert(char *s){
        int p=0;
        for(int i=0;s[i];i++){
            int k=s[i]-'a';
            p=next[p][k]?next[p][k]:next[p][k]=newnode();
        }
        ++tot[p];
    }
    void makefail(){
        std::queue<int> q;
        q.push(0);
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=0;i<26;i++){
                int v=next[u][i];
                if(v==0)next[u][i]=next[fail[u]][i];
                else q.push(v);
                if(v!=0&&u!=0)fail[v]=next[fail[u]][i];
            }
        }
    }
    int makeans(char *s){
        int ans=0;
        for(int i=0,p=0,j;s[i];i++){
            int k=s[i]-'a';
            p=next[p][k];
            for(int j=p;j&&tot[j]!=-1;j=fail[j]){
                ans+=tot[j];
                tot[j]=-1;
            }
        }
        return ans;
    }
    int main(){
    freopen("test.in","r",stdin);
        scanf("%d",&cas);
        for(int ca=1;ca<=cas;ca++){
            scanf("%d",&n);
            pos=0;newnode();
            for(int i=1;i<=n;i++){
                scanf("%s",s);
                insert(s);
            }
            makefail();
            scanf("%s",find);
            int x=makeans(find);
            printf("%d\n",x);
        }
        return 0;
    }

     

     

  • 相关阅读:
    IIS6.0远程命令执行
    非结构化和结构化数据提取
    Data Binding on Android
    微前端 [ 日常笔记 ]
    吴裕雄 python 机器学习-NBYS(2)
    吴裕雄 python 机器学习-NBYS(1)
    吴裕雄 python 爬虫(4)
    吴裕雄 python 爬虫(3)
    吴裕雄 python 爬虫(2)
    吴裕雄 python 爬虫(1)
  • 原文地址:https://www.cnblogs.com/swm8023/p/2623518.html
Copyright © 2020-2023  润新知