hdu 2222 Keywords Search ac自动机入门
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222
题意:有N(N <= 10000)个长度不超过50的模式串和一个长度不超过1e6的文本串。其中模式串可以重复。问有多少文本串在模式串中出现过。(对于相同的模式串次数仍然累加)
思路:ac自动机裸题;
KMP是先将文本串进行匹配得到失配边f[];但是并不适用于文本串较长,模式串较多的情况。因为每次查询的时间复杂度为O(n+m).n,m分别为文本串和模式串的长度;
ac自动机就是建立在Trie上,用bfs得到适配边的一个逆向过程;
即将所有的模式串建立一个状态转移,之后直接匹配文本串即可;
关键:每次看的是文本串中的当前点的后缀是那个模式串的前缀,(BFS中获得f[]的关键思想)或者就是那个模式串。之后递归打印即可;
// 358MS 32704K
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
#define MSi(a) memset(a,0x3f,sizeof(a))
#define inf 0x3f3f3f3f
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1
typedef pair<int,int> PII;
#define A first
#define B second
#define MK make_pair
typedef __int64 ll;
template<typename T>
void read1(T &m)
{
T x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
m = x*f;
}
template<typename T>
void read2(T &a,T &b){read1(a);read1(b);}
template<typename T>
void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
template<typename T>
void out(T a)
{
if(a>) out(a/);
putchar(a%+'');
}
int T,kase = ,i,j,k,n,m;
const int sigma_size = ;
const int maxn = *+;
struct Aho_Corasick{
int ch[maxn][sigma_size];
int val[maxn],f[maxn],last[maxn],cnt[maxn];
int sz;
map<string,int> ms;
Aho_Corasick(){}
void init(){sz = ; MS0(ch[]);MS0(cnt);ms.clear();}
void Insert(char *s,int v){
int u = ,n = strlen(s);
for(int i = ;i < n;i++){
int c = s[i] -'a';
if(!ch[u][c]){
MS0(ch[sz]);
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;
ms[string(s)] = v;//使用map来对应重复出现的字符串;竟然可以强转..
}
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] = ;}
}
while(!q.empty()){
int r = q.front();q.pop();
for(int c = ;c < sigma_size;c++){
int u = ch[r][c];
if(!u) {ch[r][c] = ch[f[r]][c]; 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]];
}
}
}
//从文本串中找模板;
void Find(char *T){
int n = strlen(T);
int j = ;
for(int i = ;i < n;i++){
int c = T[i] - 'a';
j = ch[j][c];//直接查找即可;
if(val[j]) print(j);
else if(last[j]) print(last[j]);
}
}
void print(int j){
if(j) {
cnt[val[j]]++;
print(last[j]);
}
}
}ac;
char p[][];
char text[];
int main()
{
read1(T);
while(T--){
ac.init();
read1(n);
rep1(i,,n){
scanf("%s",p[i]);
ac.Insert(p[i],i);
}
ac.getFail();
scanf("%s",text);
ac.Find(text);
int ans = ;
rep1(i,,n){
if(ac.cnt[ac.ms[string(p[i])]]) ans++;
}
out(ans);
puts("");
}
return ;
}
hdu 2222 Keywords Search ac自动机入门的更多相关文章
- hdu 2222 Keywords Search——AC自动机
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2222 第一道AC自动机! T了无数边后终于知道原来它是把若干询问串建一个自动机,把模式串放在上面跑:而且只 ...
- HDU 2222 Keywords Search(AC自动机模板题)
学习AC自动机请戳这里:大神blog........ 自动机的模板: #include <iostream> #include <algorithm> #include < ...
- HDU 2222 Keywords Search (AC自动机)
题意:就是求目标串中出现了几个模式串. 思路:用int型的end数组记录出现,AC自动机即可. #include<iostream> #include<cstdio> #inc ...
- hdu 2222 Keywords Search ac自动机模板
题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...
- HDU 2222 Keywords Search (AC自动机)(模板题)
<题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非 ...
- hdu2222 KeyWords Search AC自动机入门题
/** 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:题意:给定N(N <= 10000)个长度不大于50的模式串,再给定一个长度为L ...
- hdu 2222 Keywords Search - Aho-Corasick自动机
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submissio ...
- hdoj 2222 Keywords Search(AC自动机)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 思路分析:该问题为多模式匹配问题,使用AC自动机解决:需要注意的问题是如何统计该待查询的字符串包 ...
- hdu 2222 Keywords Search ac自己主动机
点击打开链接题目链接 Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
随机推荐
- 101个直接可以拿来用的JavaScript实用功能代码片段(转)
1.原生JavaScript实现字符串长度截取 function cutstr(str, len) { var temp; var icount = 0; var patrn = /[^x00-xff ...
- MySQL(5):数据表操作
表名的前缀: 两个student表,为了区分相同逻辑表名的不同应用,给逻辑表名,增加前缀 //学生管理 create table info_student ( name varchar(20), st ...
- nmblookup
域网内可以通过下述命令来根据ip地址查询其他主机名(Linux) 使用nmblookup -A ip命令查询 [admin@v015213 ~/lpmall]$ nmblookup -A 10.19. ...
- jemalloc源码结构分析(二):CPU字节对齐算法
在调用arena_malloc_small过程中,要根据申请内存大小,进行对齐计算,然后分配一个整块儿.算法如下: 1)定义一个SIZE_CLASSES宏,它主要用于生成后面两个表,small_siz ...
- 【原创】java 流星划过天空
import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import javax.s ...
- 提取数据表保存为XML文件
//连接数据库 SqlConnection con = new SqlConnection("server=****;database=****;uid=sa;pwd=********&qu ...
- ping 命令详解
Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说"ping一下某机器,看是不是开着".不能打开网页时会说"你先ping网关地址 ...
- Operation not allowed for reason code "7" on table 原因码 "7"的解决
对表进行任何操作都不被允许,提示SQLSTATE=57016 SQLCODE=-668 ,原因码 "7"的错误:SQL0668N Operation not allowed for ...
- Jquery on 事件
$(document).on("click", 'a.AAA', function(){ var flag=$(this).attr('flag'); alert(flag); } ...
- OC4_可变数组
// // main.m // OC4_可变数组 // // Created by zhangxueming on 15/6/11. // Copyright (c) 2015年 zhangxuemi ...