指针我一般都会出错,所以还是自己写数组版本。

In the modern time, Search engine came into the life of everybody like Google, Baidu, etc. 
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自动机第一题的更多相关文章

  1. hdu2222 KeyWords Search AC自动机入门题

    /** 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:题意:给定N(N <= 10000)个长度不大于50的模式串,再给定一个长度为L ...

  2. hdu2222 Keywords Search ac自动机

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=2222 题目: Keywords Search Time Limit: 2000/1000 MS ...

  3. HDU2222 Keywords Search —— AC自动机

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 Keywords Search Time Limit: 2000/1000 MS (Java/O ...

  4. HDU2222 Keywords Search [AC自动机模板]

    Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  5. HDU 2222 Keywords Search(AC自动机模板题)

    学习AC自动机请戳这里:大神blog........ 自动机的模板: #include <iostream> #include <algorithm> #include < ...

  6. HDU 2222 Keywords Search (AC自动机)(模板题)

    <题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非 ...

  7. hdu2222 Keywords Search (AC自动机板子

    https://vjudge.net/problem/HDU-2222 题意:给几个模式串和一个文本串,问文本串中包含几个模式串. 思路:贴个板子不解释. #include<cstdio> ...

  8. 【HDU 2222】Keywords Search AC自动机模板题

    参考iwtwiioi的模板写出来的.上午gty讲的并没有听懂,只好自己慢慢对着模板理解. 在HDU上为什么相同的程序提交有时T有时A!!! 奉上sth神犇的模板(不是这道题): var ch:char ...

  9. HD2222 Keywords Search(AC自动机入门题)

    然而还不是很懂=_= #include <iostream> #include <cstring> #include <algorithm> #include &l ...

随机推荐

  1. 【小而优】 如何实现 tail -f 动态显示日志时高亮显示关键字

    前言 如果你在linux下工作,那用tail -f跟踪一个日志文件的输出内容应该是家常便饭了. 但是,有时你更关心的是一些敏感字词,希望能够在动态跟踪的同时,把这些字词高亮出来,比如日志中的 ERRO ...

  2. WPF TextBox 获得焦点后,文本框中的文字全选中

    textbox.GotFocus 事件处理 Textbox.SelectAll() 是不行的, 这样处理会发生的情况是: 1) textbox1 当前没有焦点, 内容为 someText. 2) 鼠标 ...

  3. 转载:Mongodb start

    Mongodb 操作 Start MongoDB The MongoDB instance stores its data files in the /var/lib/mongo and its lo ...

  4. python - pandas或者sklearn中如何将字符形式的标签数字化

    参考:http://www.php.cn/wenda/91257.html https://www.cnblogs.com/king-lps/p/7846414.html http://blog.cs ...

  5. UVA-11294 Wedding (2-SAT)

    题目大意:一张长桌,n对夫妻,编号为0~n,这些人要坐在长桌两侧,每对夫妻不能坐在同一侧.其中,有2*m个人相互讨厌,编号为0的夫妻中的妻子不愿意让对面那一侧中有两个相互吵过架的人,找一种排座位方案. ...

  6. IOS-相机、相册

    // // ViewController.m // IOS_0301_相册和相机 // // Created by ma c on 16/3/1. // Copyright © 2016年 博文科技. ...

  7. Windows 下配置Git

    在Windows上安装git很长时间了,一直都没有配置,就是简单的使用.当然配置后就可以在任意目录下使用git命令.其实就是配置下git的环境变量. 首先,当然下载windows版本:点我下载 安装直 ...

  8. OGRE渲染流程

    本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/

  9. Caesars Cipher

    让上帝的归上帝,凯撒的归凯撒. 下面我们来介绍风靡全球的凯撒密码Caesar cipher,又叫移位密码. 移位密码也就是密码中的字母会按照指定的数量来做移位. 一个常见的案例就是ROT13密码,字母 ...

  10. JDK的KeyTool和KeyStore等加密相关

    Keytool是一个有效的安全钥匙和证书的管理工具. Java 中的 keytool.exe (位于JDK\Bin下)可以用来创建数字证书,所有的数字证书是以一条一条(用别名区别,不区分大小)地存储在 ...