在文本串中找出现次数最多的子串。

思路:AC自动机模板+修改一下print函数。

 #include<stdio.h>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<map>
#include<queue>
using namespace std;
const int SIGMA_SIZE = ;
const int MAXNODE = ;
const int MAXS = + ; map<string,int> ms; struct AhoCorasickAutomata
{
int ch[MAXNODE][SIGMA_SIZE];
int f[MAXNODE]; // fail函数
int val[MAXNODE]; // 每个字符串的结尾结点都有一个非0的val
int last[MAXNODE]; // 输出链表的下一个结点
int cnt[MAXS];
int sz; void init()
{
sz = ;
memset(ch[], , sizeof(ch[]));
memset(cnt, , sizeof(cnt));
ms.clear();
} // 字符c的编号
int idx(char c)
{
return c-'a';
} // 插入字符串。v必须非0
void insert(char *s, int v)
{
int u = , n = strlen(s);
for(int i = ; i < n; i++)
{
int c = idx(s[i]);
if(!ch[u][c])
{
memset(ch[sz], , sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;
ms[string(s)] = v;
} // 递归打印以结点j结尾的所有字符串
void print(int j)
{
if(j)
{
cnt[val[j]]++;
print(last[j]);
}
} // 在T中找模板
int find(char* T)
{
int n = strlen(T);
int j = ; // 当前结点编号,初始为根结点
for(int i = ; i < n; i++) // 文本串当前指针
{
int c = idx(T[i]);
while(j && !ch[j][c]) j = f[j]; // 顺着细边走,直到可以匹配
j = ch[j][c];
if(val[j]) print(j);
else if(last[j]) print(last[j]); // 找到了!
}
} // 计算fail函数
void getFail()
{
queue<int> q;
f[] = ;
// 初始化队列
for(int c = ; c < SIGMA_SIZE; c++)
{
int u = ch[][c];
if(u)
{
f[u] = ;
q.push(u);
last[u] = ;
}
}
// 按BFS顺序计算fail
while(!q.empty())
{
int r = q.front();
q.pop();
for(int c = ; c < SIGMA_SIZE; c++)
{
int u = ch[r][c];
if(!u) continue;
q.push(u);
int v = f[r];
while(v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
} }; AhoCorasickAutomata ac;
char text[], p[][];
int n, T; int main()
{
while(scanf("%d",&n)==&&n)
{
ac.init();
for(int i=; i<=n; i++)
{
scanf("%s",p[i]);
ac.insert(p[i],i);
}
ac.getFail();
scanf("%s",text);
ac.find(text);
int best=-;
for(int i=; i<=n; i++)
{
if(ac.cnt[i]>best)
best=ac.cnt[i];
}
printf("%d\n",best);
for(int i=; i<=n; i++)
{
if(ac.cnt[ms[string(p[i])]]==best)
{
printf("%s\n",p[i]);
}
}
}
return ;
}

uvalive 4670 Dominating Patterns的更多相关文章

  1. 【暑假】[实用数据结构]UVAlive 4670 Dominating Patterns

    UVAlive 4670 Dominating Patterns 题目:   Dominating Patterns   Time Limit: 3000MS   Memory Limit: Unkn ...

  2. UVALive 4670 Dominating Patterns --AC自动机第一题

    题意:多个模板串,一个文本串,求出那些模板串在文本串中出现次数最多. 解法:AC自动机入门模板题. 代码: #include <iostream> #include <cstdio& ...

  3. UVALive - 4670 Dominating Patterns AC 自动机

    input n 1<=n<=150 word1 word2 ... wordn 1<=len(wirdi)<=70 s 1<=len(s)<=1000000 out ...

  4. UVALive 4670 Dominating Patterns (AC自动机)

    AC自动机的裸题.学了kmp和Trie以后不难看懂. 有一些变化,比如0的定义和f的指向,和建立失配边,以及多了后缀连接数组last.没有试过把失配边直接当成普通边(一开始还是先这样写吧). #inc ...

  5. UVa Live 4670 Dominating Patterns - Aho-Corasick自动机

    题目传送门 快速的通道I 快速的通道II 题目大意 给定一堆短串,和一个文本串,问哪些短串在文本串中出现的次数最多. 我觉得刘汝佳的做法,时间复杂度有问题.只是似乎这道题短串串长太短不好卡.比如给出的 ...

  6. AC自动机 LA 4670 Dominating Patterns

    题目传送门 题意:训练指南P216 分析:求出现最多次数的字串,那么对每个字串映射id,cnt记录次数求最大就可以了. #include <bits/stdc++.h> using nam ...

  7. LA 4670 Dominating Patterns (AC自动机)

    题意:给定n个字符串和一个文本串,查找哪个字符串出现的次数的最多. 析:一匹配多,很明显是AC自动机.只需要对原来的进行修改一下,就可以得到这个题的答案, 计算过程中,要更新次数,并且要映射字符串.如 ...

  8. LA 4670 Dominating Patterns (AC自动机)

    题意:给定一个一篇文章,然后下面有一些单词,问这些单词在这文章中出现过几次. 析:这是一个AC自动机的裸板,最后在匹配完之后再统计数目就好. 代码如下: #pragma comment(linker, ...

  9. Dominating Patterns

    Dominating Patterns Time Limit:3000MS   Memory Limit:Unknown   64bit IO Format:%lld & %llu Descr ...

随机推荐

  1. C#学习笔记(二)

    1.注释:注销,解释2.单行://多行:/**/文档注释:///按enter主食要保证 别人一看就明白3.快速对期待吗:ctrl+k+d,按住ctrl不放,按k,迅速抬起,再按d(按D得时候k已经抬起 ...

  2. 如何使用PHP实现一个WebService

    WSDL WSDL(网络服务描述语言,Web Services Description Language)是一门基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问.这种文 ...

  3. UnitOfWork机制的实现和注意事项

    UnitOfWork机制 /*一点牢骚: * UnitOfWork机制的蛋疼之处: *    UnitOfWork机制,决定了插入新的实体前,要预先设置数据库中的主键Id,尽管数据库自己生产主键. * ...

  4. 微软的Dll管理方案及其变迁(Side-by-side assembly)

    本文简要介绍Side-by-side assembly技术,探讨在插件技术中使用类似方法的可能. 什么是Side-ty-side Assembly Side-by-side assembly是Wind ...

  5. Android SlidingMenu的getSupportActionBar无法找到的解决

    getSupportActionBar()方法不能用 进入Library中的src下找到SlidingFragmentActivity.java,修改 public class SlidingFrag ...

  6. php简单文件上传类

    <?php header("Content-Type:text/html; charset=utf-8"); if($_POST['submit']){ $upfiles = ...

  7. 220. Contains Duplicate III

    题目: Given an array of integers, find out whether there are two distinct indices i and j in the array ...

  8. CodeForces250B——Restoring IPv6(字符串处理)

    Restoring IPv6 DescriptionAn IPv6-address is a 128-bit number. For convenience, this number is recor ...

  9. Android数据存储(三)——SQLite

    如果需要一个更加健壮的数据存储机制,则需要使用一个关系型数据库,在Android上,则为SQLlite. SQLite的特点:轻量级.嵌入式的.关系型数据库.可移植性好,易使用,小,高效且可靠,与使用 ...

  10. Android 签名(5)用命令签名和用IDE签名

    1,用命令签名 无论用哪个 IDE 开发,最终只是用了 keytool 和 jarsigner 这两个 Java 工具来完成签名任务(在 jdk 的 bin 目录下).其中 keytool 用来生成 ...