• 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;
    }
    
  • 相关阅读:
    在cmd下执行py脚本报Traceback (most recent call last)报错解决
    git上传文件方法
    js获取元素方法和jquery语法操作元素方法
    获取config.ini文件配置的方法
    利用random随机函数实现抽奖方法
    selenium封装 运行脚本+生成测试报告+发送email
    基于KB的QA系统学习记录
    python学习记录
    manjaro + kde 使用过程中问题记录及解决方法
    linux学习记录
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10692179.html
Copyright © 2020-2023  润新知