HDU2222 Keywords Search__AC自动机
| Time Limit: 1000MS | Memory Limit: 131072KB | 64bit IO Format: %I64d & %I64u |
Description
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.
Input
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.
Output
Sample Input
5
she
he
say
shr
her
yasherhs
Sample Output
1 struct node
2 {
3 node * fail;
4 node * next[kind];
5 int count;
6 node ()
7 {
8 fail=NULL;
9 memset(next,NULL,sizeof(next));
10 count=0;
11 }
12 };
二:建立失败指针。
失败指针分为三类:
1、root的失败指针指向NULL
2、root孩子的失败指针指向root
3、其余节点的失败指针按照以下方法:沿该节点的父亲节点的失败指针查找同样有该节点的节点,把该节点的失败指针指向那个节点的该节点。如果找不到则指向root。如:该节点(1)为‘a',而该节点的父亲节点(2)为’c',则查找'c'的失败指针指向的节点(3),当然节点(3)也为’c',如果节点(3)有’a'这个孩子(节点(4)),则把节点(1)的失败指针指向节点(4),如果节点(3)没有‘a'这个孩子,则沿着沿的失败指针继续查找,直到NULL。则把失败指针指向root。
建立的方法:
由于1、2类节点的失败指针一定,而第3指针是沿着父亲的失败指针查找,所以用队列维护指针。
1 void buildac(node * root)
2 {
3 int i;
4 root->fail=NULL;
5 q.push(root);
6 while(!q.empty())
7 {
8 node *tp=q.front(),*p;
9 q.pop();
10 for(int i=0;i<26;i++)
11 {
12 if(tp->next[i]!=NULL)
13 {
14 if(tp==root)tp->next[i]->fail=root;
15 else
16 {
17 p=tp->fail;
18 while(p!=NULL)
19 {
20 if(p->next[i]!=NULL)
21 {
22 tp->next[i]->fail=p->next[i];
23 break;
24 }
25 p=p->fail;
26 }
27 if(p==NULL)tp->next[i]->fail=root;
28 }
29 q.push(tp->next[i]);
30 }
31 }
32 }
33 }
三、查询。
查询方法:指针p指向root,沿着主串的字母走,如果该节点没法走则跳到失败指针再走,如果还不能走则再跳直到到达root。如果某一个点匹配成功则沿失败指针统计对应失败指针的count。
int query(node *root)
{
int i=0,cnt=0,index;
node *p=root;
while(s[i])
{
index=s[i]-'a';
while(p->next[index]==NULL && p!=root)p=p->fail;
p=(p->next[index]==NULL)?root:p->next[index];
node *tp=p;
while(tp!=root && tp->count!=-1)
{
cnt+=tp->count;
tp->count=-1;
tp=tp->fail;
}
i++;
}
return cnt;
}
1 #include<cstdio>
2 #include<cstring>
3 #include<queue>
4
5 using namespace std;
6 const int kind=26;
7 struct node
8 {
9 node * fail;
10 node * next[kind];
11 int count;
12 node ()
13 {
14 fail=NULL;
15 memset(next,NULL,sizeof(next));
16 count=0;
17 }
18 };
19 typedef node * np;
20 queue<np>q;
21 char keyw[52],s[1000010];
22 node * root=NULL;
23 int t,n;
24 void ins(char s[],node *root)
25 {
26 node *p=root;
27 int i=0,index;
28 while(s[i])
29 {
30 index=s[i]-'a';
31 if(!p->next[index])p->next[index]=new node;
32 p=p->next[index];
33 i++;
34 }
35 p->count++;
36 }
37 void buildac(node * root)
38 {
39 int i;
40 root->fail=NULL;
41 q.push(root);
42 while(!q.empty())
43 {
44 node *tp=q.front(),*p;
45 q.pop();
46 for(int i=0;i<26;i++)
47 {
48 if(tp->next[i]!=NULL)
49 {
50 if(tp==root)tp->next[i]->fail=root;
51 else
52 {
53 p=tp->fail;
54 while(p!=NULL)
55 {
56 if(p->next[i]!=NULL)
57 {
58 tp->next[i]->fail=p->next[i];
59 break;
60 }
61 p=p->fail;
62 }
63 if(p==NULL)tp->next[i]->fail=root;
64 }
65 q.push(tp->next[i]);
66 }
67 }
68 }
69 }
70
71 int query(node *root)
72 {
73 int i=0,cnt=0,index;
74 node *p=root;
75 while(s[i])
76 {
77 index=s[i]-'a';
78 while(p->next[index]==NULL && p!=root)p=p->fail;
79 p=p->next[index];
80 p=(p==NULL)?root:p;
81 node *tp=p;
82 while(tp!=root && tp->count!=-1)
83 {
84 cnt+=tp->count;
85 tp->count=-1;
86 tp=tp->fail;
87 }
88 i++;
89 }
90 return cnt;
91 }
92 int main()
93 {
94 scanf("%d",&t);
95 while(t--)
96 {
97 root=new node;
98 scanf("%d",&n);
99 while(n--)
100 {
101 scanf("%s",keyw);
102 ins(keyw,root);
103 }
104 buildac(root);
105 scanf("%s",s);
106 printf("%d\n",query(root));
107 }
108 return 0;
109 }
HDU2222 Keywords Search__AC自动机的更多相关文章
- HDU2222 Keywords Search 【AC自动机】
HDU2222 Keywords Search Problem Description In the modern time, Search engine came into the life of ...
- 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自动机模板]
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU2222 Keywords Search(AC自动机)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- hdu2222 Keywords Search【AC自动机】
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- 【AC自动机】hdu2222 Keywords Search
AC自动机模板题,给你n个模式串和一个文本串,问你有几个模式串在文本串出现过. 注意防止重复统计 这里推荐一波郭大爷的介绍,简单易懂. http://www.bilibili.com/video/av ...
- HDU2222 Keywords Search —— AC自动机
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 Keywords Search Time Limit: 2000/1000 MS (Java/O ...
- AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)
首先,有这样一道题: 给你一个单词W和一个文章T,问W在T中出现了几次(原题见POJ3461). OK,so easy~ HASH or KMP 轻松解决. 那么还有一道例题: 给定n个长度不超过50 ...
- HDU-2222 Keywords Search 字符串问题 AC自动机
题目链接:https://cn.vjudge.net/problem/HDU-2222 题意 给一些关键词,和一个待查询的字符串 问这个字符串里包含多少种关键词 思路 AC自动机模版题咯 注意一般情况 ...
随机推荐
- mysql中order by优化的那些事儿
为了测试方便和直观,我们需要先创建一张测试表并插入一些数据: CREATE TABLE `shop` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '记 ...
- File类的特点?如何创建File类对象?Java中如何操作文件内容,什么是Io流Io流如何读取和写入文件?字节缓冲流使用原则?
重难点提示 学习目标 1.能够了解File类的特点(存在的意义,构造方法,常见方法) 2.能够了解什么是IO流以及分类(IO流的概述以及分类) 3.能够掌握字节输出流的使用(继承体系结构介绍以及常见的 ...
- Vue利用v-for渲染时表单信息出不来
今天在写项目时,Controller的值已经传入到html,但是利用vue进行渲染的时候就是出不来, 原因如下: 注意,in 之前的空格.
- 盘点 Java 开发 2020 年发生的几件大事,你必须得知道!
2021 年了,在过去的一年 Java 软件开发行业都发生了哪些重大事件呢? 这篇栈长带大家回顾一下,其实在元旦的<滚蛋吧,2020>也略有介绍,这篇就更加详细的总结一下. 1.Java ...
- TurtleBot3 Waffle (tx2版华夫)(12)建图-hector建图
1)[Remote PC] 启动roscore $ roscore 2)[TurBot3] 启动turbot3 $ roslaunch turbot3_bringup minimal.launch 3 ...
- netcore.ydal可能是东半球最好ORM框架
typora-copy-images-to: static ydal 项目框架介绍 可能是东半球最好netcore ORM框架,目前暂时支持mysql.mssql,其核心设计目标是开发迅速.学习简单. ...
- Modbus 协议图文详解
1.概论 Modbus是一种串行通信协议,由于其协议简单易用,且没有版权要求,目前已经成为工业领域通信协议的实时标准.ModBus协议是又施耐德电气的前身Modicon公司在1979年提出的.Modb ...
- C#处理医学图像(二):基于Hessian矩阵的医学图像增强与窗宽窗位
根据本系列教程文章上一篇说到,在完成C++和Opencv对Hessian矩阵滤波算法的实现和封装后, 再由C#调用C++ 的DLL,(参考:C#处理医学图像(一):基于Hessian矩阵的血管肺纹理骨 ...
- Laya Ts 简易对象池
ts版本的简易对象池 ,目前主要支持3D的物体,也可以将其改成其他类型 要使用首先调用InitPool 方法 `/* 使用说明: 使用必须先调用 InitPool 方法将对象池初始化 然后 Deque ...
- 【Java基础】网络编程
网络编程 网络编程概述 网络编程的目的:直接或简洁地通过网络协议与其他计算机实现数据交换,进行通讯. 网络编程的两个主要问题: 如果准确地定位网络上一台或多台主机,并定位主机上的特定应用: 找到主机后 ...