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

    题目描述

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

    输入输出格式

    输入格式:

    输入含多组数据。

    每组数据的第一行为一个正整数,表示共有个模式串,

    接下去行,每行一个长度小于等于的模式串。下一行是一个长度小于等于的文本串

    输入结束标志为

    输出格式:

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

    输入输出样例

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

    个人认为没有什么特别大的变化,记录一下,然后简单运用一下,就ok了,纯裸题,不过用c++自带的queue貌似有些慢,
    应该可以优化一下。
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<cstring>
     6 #include<queue>
     7 using namespace std;
     8 
     9 int n,cnt=1,fzy[157];
    10 char s[157][77];
    11 struct Node
    12 {
    13     int c[26],suf,flag,mark;
    14     void init()
    15     {
    16         suf=flag=mark=0;
    17         memset(c,0,sizeof(c));    
    18     }    
    19 }tree[1000007];
    20 
    21 void init()
    22 {
    23     memset(fzy,0,sizeof(fzy));
    24     for (int i=0;i<=cnt;i++)
    25         tree[i].init();
    26     cnt=1;    
    27 }
    28 void Ins(int num)
    29 {
    30     int head=1,l=strlen(s[num]);
    31     for (int i=0;i<l;i++)
    32     {
    33         int now=s[num][i]-'a';
    34         if (!tree[head].c[now]) tree[head].c[now]=++cnt;
    35         head=tree[head].c[now];
    36     }
    37     tree[head].flag++,tree[head].mark=num;
    38 }
    39 void Make_AC()
    40 {
    41     for (int i=0;i<26;i++) tree[0].c[i]=1;
    42     int head=0,tail=1;
    43     queue<int>q;
    44     while (!q.empty()) q.pop();
    45     tree[1].suf=0;
    46     q.push(1);
    47     while (!q.empty())
    48     {
    49         int u=q.front();
    50         q.pop();
    51         for (int i=0;i<26;i++)
    52             if (tree[u].c[i])
    53             {
    54                 tree[tree[u].c[i]].suf=tree[tree[u].suf].c[i];
    55                 q.push(tree[u].c[i]);
    56             }
    57             else tree[u].c[i]=tree[tree[u].suf].c[i];
    58     }
    59 }
    60 void Solve()
    61 {
    62     char s1[1000007];
    63     scanf("%s",s1);
    64     int head=1,len=strlen(s1);
    65     for (int i=0;i<len;i++)
    66     {
    67         int now=s1[i]-'a';
    68         head=tree[head].c[now];
    69         for (int j=head;j&&tree[j].flag!=-1;j=tree[j].suf)
    70             fzy[tree[j].mark]+=tree[j].flag;
    71     }
    72     int x=fzy[1];
    73     for (int i=2;i<=n;i++)
    74         if (x<fzy[i]) x=fzy[i];
    75     printf("%d
    ",x);    
    76     for (int i=1;i<=n;i++) 
    77         if (x==fzy[i]) printf("%s
    ",s[i]);
    78 }
    79 int main()
    80 {    
    81     while (scanf("%d",&n)&&n)
    82     {
    83         init();
    84         for (int i=1;i<=n;i++)
    85             {scanf("%s",s[i]);Ins(i);}
    86         Make_AC();
    87         Solve();
    88     }
    89 }
     
  • 相关阅读:
    wifi详解(四)
    wifi详解(三)
    wifi详解(二)
    wifi详解(一)
    Linux下GPIO驱动
    wpa_cli调试工具的使用
    WAPI
    java spring使用Jackson过滤
    JPA 一对多双向映射 结果对象相互迭代 造成堆栈溢出问题方法
    Javassist指引(二)--ClassPool
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7241810.html
Copyright © 2011-2022 走看看