zoukankan      html  css  js  c++  java
  • AC自动机(加强版)

    题目描述

    NN个由小写字母组成的模式串以及一个文本串TT。每个模式串可能会在文本串中出现多次。你需要找出哪些模式串在文本串TT中出现的次数最多。

    输入输出格式

    输入格式:

    输入含多组数据。

    每组数据的第一行为一个正整数NN,表示共有NN个模式串,1 leq N leq 1501N150。

    接下去NN行,每行一个长度小于等于7070的模式串。下一行是一个长度小于等于10^6106​​的文本串TT。

    输入结束标志为N=0N=0。

    输出格式:

    对于每组数据,第一行输出模式串最多出现的次数,接下去若干行每行输出一个出现次数最多的模式串,按输入顺序排列。

    输入输出样例

    输入样例#1:
    2
    aba
    bab
    ababababac
    6
    beta
    alpha
    haha
    delta
    dede
    tata
    dedeltalphahahahototatalpha
    0
    输出样例#1:
    4
    aba
    2
    alpha
    haha


    ac自动机,last指针版
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int  maxn = 100001;
    int n;
    char s[maxn][101];
    char ss[maxn*10];
    int ans=0;
    struct Aho_Corasick_automato {
        int sz;
        int ch[maxn][26];
        int cnt[maxn];
        int val[maxn];
        int last[maxn];
        int fail[maxn];
        int num;
        void init() {
            memset(ch[0],0,sizeof(ch[0]));
            memset(cnt,0,sizeof(cnt));
            sz=1;
        }
        void insert(char *s,int num) {
            int len=strlen(s);
            int u=0;
            for(int i=0; i<len; ++i) {
                int v=(s[i]-'a');
                if(!ch[u][v]) {
                    memset(ch[sz],0,sizeof(ch[sz]));
                    val[sz]=0;
                    ch[u][v]=sz++;
                }
                u=ch[u][v];
            }
            val[u]=num;
        }
        void get_fail() {
            fail[0]=0;
            queue<int>que;
            for(int i=0; i<26; i++) {
                int u=ch[0][i];
                if(u) {
                    fail[u]=0;
                    que.push(u);
                }
            }
            while(!que.empty()) {
                int u=que.front();
                que.pop();
                for(int i=0; i<26; i++) {
                    int v=ch[u][i];
                    if(!v) {
                        ch[u][i]=ch[fail[u]][i];
                        continue;
                    }
                    que.push(v);
                    int k=fail[u];
                    fail[v]=ch[k][i];
                    last[v]=val[fail[v]] ? fail[v] : last[fail[v]];
                }
            }
        }
        void work(int x) {
            if(x) {
                cnt[val[x]]++;
                work(last[x]);
            }
        }
        void find(char *s) {
            int len=strlen(s);
            int u=0;
            for(int i=0; i<len; i++) {
                int v=(s[i]-'a');
                if(!ch[u][v])u=fail[u];
                while(u&&!ch[u][v])
                    u=fail[u];
                u=ch[u][v];
                if(val[u])
                    work(u);
                else if(last[u])
                    work(last[u]);
            }
        }
    } ac;
    
    int main() {
    
    
        while(scanf("%d",&n)==1&&n!=0) {
            ac.init();
            for(int i=1; i<=n; i++) {
                scanf("%s",s[i]);
                ac.insert(s[i],i);
            }
            ac.get_fail();
            scanf("%s",ss);
            ac.find(ss);
            int ans=0,r;
            for(int i=1;i<=n;i++)
                if(ac.cnt[i]>ans)ans=ac.cnt[i],r=i;;
            printf("%d
    ",ans);
             for(int r=1;r<=n;r++)
                if(ac.cnt[r]==ans)
                    printf("%s
    ",s[r]);
            }
        return 0;
    }


  • 相关阅读:
    Using Redis as Django's session store and cache backend
    Celery 和 Redis 入门
    centos 安装 rabbitmq
    CentOS 6 安装 Python3.5以及配置Django
    python metaclass 入门简介
    uWSGI其三:uWSGI搭配Nginx使用
    CentOS 6.5 安装 Nginx 1.7.8 教程
    基于nginx和uWSGI在Ubuntu上部署Djan
    CentOS 6.5 下安装 Redis 2.8.7
    查看Selinux和关闭Selinux
  • 原文地址:https://www.cnblogs.com/sssy/p/7259284.html
Copyright © 2011-2022 走看看