zoukankan      html  css  js  c++  java
  • UVA1449 Dominating Patterns

    思路

    对所有模式串建AC自动机
    在AC自动机上跑文本串,得出每个模式串的出现次数,输出即可

    AC自动机中的fail指针的意思是指向当前节点的最长的在Trie中存在和该最长后缀相等的前缀的节点

    我的AC自动机写法以0为根,0为中止条件

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    int Trie[12000][26],Nodecnt,root,fail[12000],isend[12000],cnt[12000],n,ans;
    char s[1001000],t[12000][100];
    void insert(char *s,int len,int inq){
        int o=root;
        for(int i=0;i<len;i++){
            if(!Trie[o][s[i]-'a'])
                Trie[o][s[i]-'a']=++Nodecnt;
            o=Trie[o][s[i]-'a'];
        }
        isend[o]=inq;
    }
    queue<int> q;
    void build_AC(void){
        for(int i=0;i<26;i++)
            if(Trie[root][i]){
                fail[Trie[root][i]]=root;
                q.push(Trie[root][i]);
            }
        while(!q.empty()){
            int x=q.front();
            q.pop();
            for(int i=0;i<26;i++){
                if(Trie[x][i]){
                    fail[Trie[x][i]]=Trie[fail[x]][i];
                    q.push(Trie[x][i]);
                }
                else
                    Trie[x][i]=Trie[fail[x]][i];
            }
        }
    }
    void query(char *s,int len){
        int o=root;
        for(int i=0;i<len;i++){
            o=Trie[o][s[i]-'a'];
            int p=o;
            while(p){
                if(isend[p])
                    cnt[isend[p]]++;
                p=fail[p];
            }
        }
    }
    void init(void){
        Nodecnt=0;
        root=0;
        memset(Trie,0,sizeof(Trie));
        memset(fail,0,sizeof(fail));
        memset(isend,0,sizeof(isend));
        memset(cnt,0,sizeof(cnt));
        ans=0;
    }
    int main(){
        while(scanf("%d",&n)==1&&n){
            init();
            for(int i=1;i<=n;i++){
                scanf("%s",t[i]);
                insert(t[i],strlen(t[i]),i);
            }
            build_AC();
            scanf("%s",s);
            query(s,strlen(s));
            for(int i=1;i<=n;i++)
               ans=max(ans,cnt[i]);
            printf("%d
    ",ans);
            for(int i=1;i<=n;i++)
                if(cnt[i]==ans)
                    printf("%s
    ",t[i]); 
        }
        return 0;
    }
    
  • 相关阅读:
    中文分词技术
    布隆过滤器(Bloom Filter)详解
    真正理解Mysql的四种隔离级别
    从内核文件系统看文件读写过程
    如何评价腾讯开源的消息中间件TubeMQ?
    零拷贝(Zero-copy)及其应用详解
    深入了解RabbitMQ
    (四)下载利器aria2
    (三)轻量级文件服务器filebrowser
    log4j 2整理
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10692179.html
Copyright © 2011-2022 走看看