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 ...
随机推荐
- codeforces 484B - LubaAndTicket - 贪心
2017-08-22 10:54:00 writer:pprp 题意如下: 给你6个数组,你的操作可以是更改某一位的数字成为0-9之间任意一个数,要求前三个数字的和与后三个数字的和相等. 问你最少用几 ...
- linux下增加useradd提示existing lock file /etc/subgid.lock without a PID
# useradd git -g git useradd: existing lock file /etc/subgid.lock without a PID useradd: cannot lock ...
- JSch 实现 SSH 端口转发
package com.yinger.webservice.test; import java.sql.Connection; import java.sql.DriverManager; impor ...
- LeetCode第[98]题(Java):Validate Binary Search Tree(验证二叉搜索树)
题目:验证二叉搜索树 难度:Medium 题目内容: Given a binary tree, determine if it is a valid binary search tree (BST). ...
- poi读取excel转对象,格式转换帮助类
//格式转换//value:原数据,parmtype:方法参数类型,cellType 单元格类型public static Object formatd(String value, String pa ...
- oracle的批量插入sql
insert into persons (id_p, lastname , firstName, city ) values (200,'haha' , 'deng' , 'shenzhen'), ( ...
- The tilde ( ~ ) operator in JavaScript
From the JavaScript Reference on MDC, ~ (Bitwise NOT) Performs the NOT operator on each bit. NOT a y ...
- Android6.0------权限管理
此博客主要谈谈Android6.0的权限,关于其他6.0的知识 请看https://developer.android.com/about/versions/marshmallow/android-6 ...
- 设计模式--桥梁模式C++实现
1定义 将抽象和实现解耦,使得两者可以独立变化 2类图 3实现 #pragma once #include<iostream> using namespace std; class Imp ...
- python - pandas或者sklearn中如何将字符形式的标签数字化
参考:http://www.php.cn/wenda/91257.html https://www.cnblogs.com/king-lps/p/7846414.html http://blog.cs ...