HDU2222 Keywords Search ac自动机第一题
指针我一般都会出错,所以还是自己写数组版本。
Wiskey also wants to bring this feature to his image retrieval system.
Every image have a long description, when users type some keywords to find the image, the system will match the keywords with description of image and show the image which the most keywords be matched.
To simplify the problem, giving you a description of image, and some keywords, you should tell me how many keywords will be match.
InputFirst line will contain one integer means how many cases will follow by.
Each case will contain two integers N means the number of keywords and N keywords follow. (N <= 10000)
Each keyword will only contains characters 'a'-'z', and the length will be not longer than 50.
The last line is the description, and the length will be not longer than 1000000.
OutputPrint how many keywords are contained in the description.Sample Input
1
5
she
he
say
shr
her
yasherhs
Sample Output
3
第一版:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int maxn=;
int Next[maxn][],End[maxn],fail[maxn];
int cnt,root=,ans;//root不能为0
void _init()
{
memset(Next,,sizeof(Next));
memset(End,,sizeof(End));
memset(fail,,sizeof(fail));
ans=;cnt=;
}
void _insert(char s[])
{
int L=strlen(s);
int now=root;
for(int i=;i<L;i++){
if(!Next[now][s[i]-'a']) Next[now][s[i]-'a']=++cnt;
now=Next[now][s[i]-'a'];
}
End[now]++;
}
void _build()//bfs
{
queue<int>q;
q.push(root);
while(!q.empty()){
int Now=q.front();q.pop();
for(int i=;i<;i++){
if(Next[Now][i]){
if(Now==root) fail[Next[Now][i]]=root;
else{
int p=fail[Now];
while(p){//给儿子们找对象
if(Next[p][i]){
fail[Next[Now][i]]=Next[p][i];
break;//找到了就停止
}
p=fail[p];
}
if(!p) fail[Next[Now][i]]=root;//不晓得?
}
q.push(Next[Now][i]);
}
}
}
}
void _query(char s[])
{
int L=strlen(s);
int Now=root;
for(int i=;i<L;i++){
int x=s[i]-'a';
while(Now!=root&&!Next[Now][x]) Now=fail[Now];
Now=Next[Now][x];
if(!Now) Now=root;//不晓得?
int tmp=Now;
while(tmp!=root){
if(End[tmp]>=){
ans+=End[tmp];
End[tmp]=-;//避免重复
}
else break;
tmp=fail[tmp];
}
}
}
int main()
{
char s[];
char c[maxn] ;
int n,j,i,T;
scanf("%d",&T);
while(T--){ _init();
scanf("%d",&n);
for(i=;i<=n;i++){
scanf("%s",s);
_insert(s);//单词
}
scanf("%s",c); _build();
_query(c);//文章 printf("%d\n",ans); }
return ;
}
稍微改进版:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int maxn=;
int Next[maxn][],End[maxn],fail[maxn];
int cnt,root=,ans;
int q[],tail,head;
void _init()
{
//不要memset只要200ms
ans=;cnt=;fail[root]=-;//root的fail不能等于本身,不然不能重新开始。
head=tail=;End[root]=;
for(int i=;i<;i++) Next[root][i]=;
}
void _insert(char s[])
{
int now=root;
for(int i=;s[i];i++){
if(!Next[now][s[i]-'a']) {
Next[now][s[i]-'a']=++cnt;
fail[cnt]=;
End[cnt]=;
for(int i=;i<;i++) Next[cnt][i]=;
}
now=Next[now][s[i]-'a'];
}
End[now]++;
}
void _build()//bfs
{
q[++head]=root;
while(tail<head){
int Now=q[++tail];
for(int i=;i<;i++){
if(Next[Now][i]){
if(Now==root) fail[Next[Now][i]]=root;
else{
int p=fail[Now];
while(p!=-){//给儿子们找对象
if(Next[p][i]){
fail[Next[Now][i]]=Next[p][i];
break;//找到了就停止
}
p=fail[p];//配对
}
if(p==-) {
fail[Next[Now][i]]=root;//重新开始
}
}
q[++head]=Next[Now][i];
}
}
}
}
void _query(char s[])
{
int L=strlen(s);
int Now=root;
for(int i=;i<L;i++){
int x=s[i]-'a';
while(Now!=root&&!Next[Now][x]) Now=fail[Now];
Now=Next[Now][x];
if(Now==-) Now=root;//即使失败,也不气馁,一切从零开始
int tmp=Now;
while(tmp!=root){
if(End[tmp]>){
ans+=End[tmp];
End[tmp]=-;//避免重复
}
else break;
tmp=fail[tmp];
}
}
}
int main()
{
char s[];
char c[maxn] ;
int n,j,i,T;
scanf("%d",&T);
while(T--){ _init();
scanf("%d",&n);
for(i=;i<=n;i++){
scanf("%s",s);
_insert(s);//单词
}
scanf("%s",c); _build();
_query(c);//文章 printf("%d\n",ans); }
return ;
}
HDU2222 Keywords Search ac自动机第一题的更多相关文章
- hdu2222 KeyWords Search AC自动机入门题
/** 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:题意:给定N(N <= 10000)个长度不大于50的模式串,再给定一个长度为L ...
- hdu2222 Keywords Search ac自动机
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2222 题目: Keywords Search Time Limit: 2000/1000 MS ...
- HDU2222 Keywords Search —— AC自动机
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 Keywords Search Time Limit: 2000/1000 MS (Java/O ...
- HDU2222 Keywords Search [AC自动机模板]
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU 2222 Keywords Search(AC自动机模板题)
学习AC自动机请戳这里:大神blog........ 自动机的模板: #include <iostream> #include <algorithm> #include < ...
- HDU 2222 Keywords Search (AC自动机)(模板题)
<题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非 ...
- hdu2222 Keywords Search (AC自动机板子
https://vjudge.net/problem/HDU-2222 题意:给几个模式串和一个文本串,问文本串中包含几个模式串. 思路:贴个板子不解释. #include<cstdio> ...
- 【HDU 2222】Keywords Search AC自动机模板题
参考iwtwiioi的模板写出来的.上午gty讲的并没有听懂,只好自己慢慢对着模板理解. 在HDU上为什么相同的程序提交有时T有时A!!! 奉上sth神犇的模板(不是这道题): var ch:char ...
- HD2222 Keywords Search(AC自动机入门题)
然而还不是很懂=_= #include <iostream> #include <cstring> #include <algorithm> #include &l ...
随机推荐
- 转载 - POJ分类很好很有层次感
from http://blog.csdn.net/zzycsx/article/details/49103451 OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2 ...
- RabbitMQ入门(5)——主题(Topic)
前面我们介绍了通过使用direct exchage,改善了fanout exchange只能进行虚拟广播的方式.尽管如此,直接交换也有自身的局限,它不能基于多个条件路由. 在我们的日志系统中,也许我们 ...
- spring的静态代理和动态代理
Java静态代理 Jdk动态代理 java代理模式 即Proxy Pattern,23种java常用设计模式之一.代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问. 原理: 代理模式的主要 ...
- 设计模式--访问者模式C++实现
访问者模式C++实现 1定义Visitor Pattern 封装一些作用于某种数据结构中各元素的操作,他可以在不改变数据结构的前提下定义作用于这些元素新的操作 2类图 角色分析 Visitor抽象访问 ...
- Verilog HDL Test Bench
As digital systems becomes more complex,it becomes increasingly important to verify the functionalit ...
- MyCat的分片规则
1. 枚举法: 通过在配置文件中配置可能的枚举id,自己配置分片,使用规则: <tableRule name="sharding-by-intfile"> <ru ...
- js鼠标键禁用功能
页面完全禁用右键 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- Winform 导航菜单的方法
http://blog.163.com/kunkun0921@126/blog/static/169204332201171610619611/ 第一种:使用OutlookBar第三方控件 第二种:使 ...
- LeetCode OJ:Gas Station(加油站问题)
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You ...
- flask框架中勾子函数的使用
在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如: 在请求开始时,建立数据库连接: 在请求开始时,根据需求进行权限校验: 在请求结束时,指定数据的交互格式: 为了让每个视图函数避免编 ...