题目链接https://vjudge.net/problem/UVA-1449

题目大意:给出N(N<150)个长度不超过L(70)的匹配串和一个长度小于1e6的文本串,在文本串中找出出现次数最多的匹配串,如果有多个匹配串满足条件,按输入顺序依次输出。

AC自动机复杂度约为O((N+M)*L) //N为匹配串个数,M为文本串长度,L为匹配串平均长度,时间3s,可行

用了两个map方便统计字符串出现的次数和根据节点编号找到对应的字符串,注意这里统计时不必将AC[u].cnt清零;

 #include<bits/stdc++.h>
using namespace std;
const int MAX_T=;
const int MAX_NOD=*+;
const int MAX_SIG=;
const int MAX_P=;
map<string,int> M;
map<int,string> _M;
char T[MAX_T];
struct node{
int next[MAX_SIG];
int fail,cnt;
};
struct aho
{
node AC[MAX_NOD];
int size; int idx(char c){return c-'a';} void init()
{
for(int i=;i<MAX_NOD;++i)
memset(AC[i].next,,sizeof(AC[i].next)),AC[i].cnt=;
size=;
AC[].fail=-;
} void insert(char *S)
{
int n=strlen(S);
int u=;
for(int i=;i<n;++i)
{
int c=idx(S[i]);
if(!AC[u].next[c]) AC[u].next[c]=size++;
u=AC[u].next[c];
}
AC[u].cnt++;
_M[u]=S;
//cout<<"---"<<_M[u]<<" "<<AC[u].cnt<<endl;
} void build_fail()
{
queue<int> q;
q.push();
AC[].fail=-;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=;i<MAX_SIG;++i)
{
if(AC[u].next[i]){
if(!u) AC[AC[u].next[i]].fail=;
else{
int v=AC[u].fail;
while(v!=-&&AC[v].next[i]==) v=AC[v].fail;
if(v==-) AC[AC[u].next[i]].fail=;
else AC[AC[u].next[i]].fail=AC[v].next[i];
}
q.push(AC[u].next[i]);
}
}
}
} void cal(int u)
{
while(u!=-){//cout<<"ppp"<<endl;
M[_M[u]]+=AC[u].cnt;
// AC[u].cnt=0;
u=AC[u].fail;
}
} int solve(char *T)
{
int now=;
int n=strlen(T);
for(int i=;i<n;++i)
{
int c=idx(T[i]);
if(AC[now].next[c]) now=AC[now].next[c];
else{
int v=AC[now].fail;
while(v!=-&&AC[v].next[c]==) v=AC[v].fail;
if(v==-){now=;}
else{
now=AC[v].next[c];
}
}
if(AC[now].cnt){
cal(now);
}
}
}
};
int main()
{
int n;
char P[MAX_P];
string x[];
while(cin>>n&&n){
M.clear();
_M.clear();
aho a;
a.init();
for(int i=;i<=n;++i)
{
cin>>P;
x[i]=P;
M[P]=;
a.insert(P);
}
cin>>T;
a.build_fail();
int ans=;
a.solve(T);
for(int i=;i<=n;++i)
ans=max(ans,M[x[i]]);
cout<<ans<<endl;
for(int i=;i<=n;++i)
{
if(M[x[i]]==ans) cout<<x[i]<<endl;
}
}
return ;
}
/*
2
aba
bab
ababababac
6
beta
alpha
haha
delta
dede
tata
dedeltalphahahahototatalpha
0
*/

uva-1449-AC自动机的更多相关文章

  1. Uva 11468 AC自动机或运算

    AC自动机 UVa 11468 题意:给一些字符和各自出现的概率,在其中随机选择L次,形成长度为L的字符串S,给定K个模板串,求S不包含任意一个串的概率. 首先介绍改良版的AC自动机: 传统的AC自动 ...

  2. UVa 11468 (AC自动机 概率DP) Substring

    将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点. 然后问题就变成了在Tire树上走L步且不经过禁止节点的概率. 根据全概率公式用记忆化搜索求解. #include <cs ...

  3. UVA - 11468 (AC自动机+动态规划)

    建立AC自动机,把AC自动机当做一张图,在上面跑L个节点就行了. 参考了刘汝佳的代码,发现可能有一个潜在的Bug--如果模式串中出现了没有指定的字符,AC自动机可能会建立出错. 提供一组关于这个BUG ...

  4. Substring UVA - 11468 AC自动机+概率DP

    题意: 给出一些字符和各自对应的选择概率,随机选择L次后得到一个长度为L的随机字符串S. 给出K个模板串,计算S不包含任何一个模板串的概率 dp[i][j]表示走到AC自动机 i 这个节点 还需要走 ...

  5. UVA 11468 AC 自动机

    首先我们应该是枚举 L个位置上的每个字符来得到最终概率 然后AC自动机的作用就是为了判断你枚举的地方是否对应了单词节点,如果对应了,就肯定要不得 #include <iostream> # ...

  6. UVa 11019 (AC自动机 二维模式串匹配) Matrix Matcher

    就向书上说得那样,如果模式串P的第i行出现在文本串T的第r行第c列,则cnt[r-i][c]++; 还有个很棘手的问题就是模式串中可能会有相同的串,所以用repr[i]来记录第i个模式串P[i]第一次 ...

  7. UVA 11468 AC自动机入门题 记忆化概率dp+ac自动机

    /** 链接:https://vjudge.net/problem/UVA-11468 详见lrj训练指南P218 我的是反向求存在模板串的概率. dp[i][j]表示当前i位置选择字符,前面i-1个 ...

  8. uva 11468 AC自动机+概率DP

    #include<cstdio> #include<cstring> #include<queue> #include<cstdio> #include ...

  9. UVa 1449 - Dominating Patterns (AC自动机)

    题目大意:给出多个字符串模板,并给出一个文本串,求在文本串中出现最多的模板,输出最多的次数并输出该模板(若有多个满足,则按输入顺序输出). 思路:赤裸裸的 AC自动机,上模板. 代码: #includ ...

  10. UVA 11019 Matrix Matcher(ac自动机)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

随机推荐

  1. 聚合的安全类导航、专业的安全知识学习平台——By Me:)

    以“基于对抗的安全研发”为初衷,让大家在工作中始终有安全意识.安全思维和安全习惯,几年前自己搭建了面向公司内部全员的安全晨报.现在站在“用户“的角度回头看看,觉得科目设计等很多方面都还有很多的不足: ...

  2. 华为大数据项目fusionInsight

    项目简述:基于开源Hadoop2.0架构的集群网络,进行海量数据的分布式计算.由于Hadoop集群规模不断扩大,而搭建一个同等规模的测试集群需要一笔昂贵的开销.目前有100台左右物料,期望预测计算节点 ...

  3. Java NIO2 File API介绍

    Introduction to the Java NIO2 File API GitHub NIO2中的文件API是Java 7附带的Java平台的主要新功能之一,特别是新的文件系统API的一个子集以 ...

  4. beego——表单验证

    表单验证是用于数据验证和错误收集的模块. 安装: go get github.com/astaxie/beego/validation 测试: go test github.com/astaxie/b ...

  5. python 中的 re.compile 函数(转)

    1. 使用re.compile re模块中包含一个重要函数是compile(pattern [, flags]) ,该函数根据包含的正则表达式的字符串创建模式对象.可以实现更有效率的匹配.在直接使用字 ...

  6. linux redhat下oracle11G安装

    首先由于使用的是虚拟机,所有要修改ip 在LINUX下修改IP分为二种情况, 1.调试时修改IP,仅在当前生效,重启后恢复为原有IP ifconfig eth0 192.168.63.27 netma ...

  7. nor flash的一般操作与分析

    是现在市场上两种主要的非易失闪存技术.Intel于1988年首先开发出NOR Flash 技术,彻底改变了原先由EPROM(Electrically Programmable Read-Only-Me ...

  8. shell-一些有趣的使用

    1. 对字符串进行MD5加密  echo test |md5sum|awk '{print $1}' 字符串数量很多时可以这样做: echo test |md5sum|awk '{print $1}' ...

  9. Linux系统下Git操作命令整理

    1.显示当前的配置信息 git config --list 2. 创建repo从别的地方获取 git clone git://git.kernel.org/pub/scm/git/git.git 自己 ...

  10. fabric文件上传打包与校验