Keywords Search HDU - 2222 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
题意:
T组输入,对于每组数据有n个模式串,最后输入一个待求串。让你求这个待求串中有多少种模式串
注意:这个模式串可能会重复,重复的话要算做多个,不能算作一个
代码:
1 /*
2 代码中:
3 叶节点:代表此节点下没有子节点
4 根节点:就是树的根
5 子节点:就是这个节点的直接相连的节点(直系节点)
6
7 此代码:
8 用题目所给模式串构成一颗字典树
9 然后找出来给出的待求串中有多少种模式串(如果模式串中有重复的,那么也算作多个,不算一个)
10
11 */
12 #include<stdio.h>
13 #include<iostream>
14 #include<string.h>
15 #include<algorithm>
16 #include<queue>
17 using namespace std;
18 const int maxn=5e5+10;
19 const int N=26;
20 typedef long long ll;
21 struct Trie
22 {
23 int next[maxn][N],fail[maxn],ends[maxn];
24 int root,L;
25 int New_node() //创建一个新节点
26 {
27 for(int i=0;i<N;++i)
28 {
29 next[L][i]=-1; //每次初始化新节点
30 }
31 ends[L++]=0; //每次初始化新节点
32 return L-1;
33 }
34 void init() //创建根节点
35 {
36 L=0;
37 root=New_node();
38 }
39 void inserts(char s[]) //往字典树里面插入新字符串
40 {
41 int len=strlen(s);
42 int now=root;
43 for(int i=0;i<len;++i)
44 {
45 if(next[now][s[i]-'a']==-1)
46 next[now][s[i]-'a']=New_node();
47 now=next[now][s[i]-'a'];
48 }
49 ends[now]++; //字典树的叶节点要标记,如果走到这个位置就代表这种模式串出现过
50 }
51 void build()
52 {
53 queue<int>r;
54 fail[root]=root;
55 for(int i=0;i<N;++i) //先给字典树根节点下的N个子节点初始化一下
56 {
57 if(next[root][i]==-1) //代表字典树上都没有i这个分支,对于这些节点的下一级就直接指向根节点就完了
58 {
59 next[root][i]=root;
60 }
61 else //字典树上有i这个分支的,就要改变它的fail(即,失败指针)的值
62 {
63 fail[next[root][i]]=root;
64 r.push(next[root][i]);
65 }
66 }
67 while(!r.empty())
68 {
69 int now=r.front();
70 r.pop();
71 for(int i=0;i<N;++i)
72 {
73 if(next[now][i]==-1)
74 {
75 next[now][i]=next[fail[now]][i];
76 //代表now在叶节点处,此时往下一个节点走就直接通过now节点失败指针进行跳转
77 }
78 else
79 {
80 fail[next[now][i]]=next[fail[now]][i]; //此节点的子节点的失败指针就是此节点失败指针对应字符位置
81 r.push(next[now][i]);
82 }
83 }
84 }
85 }
86 int query(char s[])
87 {
88 int len=strlen(s);
89 int now=root;
90 int res=0;
91 for(int i=0;i<len;++i)
92 {
93 now=next[now][s[i]-'a']; //这个now就保证了我们找的肯定是这个s字符串中的一部分
94 int temp=now; //这就是一直找,找到了就加1,找不到就通过失败指针看其他地方能不能找到
95 while(temp!=root) //尝试这个节点的失败指针能不能找到模式串
96 {
97 res+=ends[temp]; //因为我们要找出来s串中包含几种模式串,所以要有赋值0操作
98 ends[temp]=0;
99 temp=fail[temp];
100 }
101 }
102 return res;
103 }
104 };
105 char s[1000010];
106 Trie ac;
107 int main()
108 {
109 int t;
110 scanf("%d",&t);
111 while(t--)
112 {
113 int n;
114 scanf("%d",&n);
115 ac.init();
116 while(n--)
117 {
118 scanf("%s",s); //这个就是模式串
119 ac.inserts(s);
120 }
121 ac.build();
122 scanf("%s",s); //这个是待求串
123 printf("%d\n",ac.query(s));
124 }
125 return 0;
126 }
Keywords Search HDU - 2222 AC自动机板子题的更多相关文章
- hdu 2222(AC自动机模版题)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU 2222 AC自动机模板题
题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...
- HDU 2222 AC自动机(模版题)
Keywords Search Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- HDU 2222 AC自动机 裸题
题意: 问母串中出现多少个模式串 注意ac自动机的节点总数 #include <stdio.h> #include <string.h> #include <queue& ...
- HDU 2222 AC自动机模版题
所学的AC自动机都源于斌哥和昀神的想法. 题意:求目标串中出现了几个模式串. 使用一个int型的end数组记录,查询一次. #include <cstdio> #include <c ...
- AC日记——Keywords Search hdu 2222
2222 思路: ac自动机模板题: 代码: #include <cstdio> #include <cstring> #include <iostream> #i ...
- HDU 3065 (AC自动机模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...
- HDU 2896 (AC自动机模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...
- HDU-2222 Keywords Search 字符串问题 AC自动机
题目链接:https://cn.vjudge.net/problem/HDU-2222 题意 给一些关键词,和一个待查询的字符串 问这个字符串里包含多少种关键词 思路 AC自动机模版题咯 注意一般情况 ...
随机推荐
- Linux学习笔记 | 配置ssh
目录: SSH的必要性 将默认镜像源修改为清华镜像源 Linux安装ssh软件 使用putty软件实现ssh连接 Windows下安装winscp SSH的必要性 一般服务器都位于远程而非本地,或者及 ...
- 【ASM】查看ASM磁盘组剩余容量和总容量
col total_size for a10; col free_size for a20; select name,total_mb/1024 || 'G' as total_size , free ...
- CTFshow萌新赛-萌新福利
下载链接文件 拿到show.bin文件 使用010Editor工具打开文件 做取反操作 取反后可以看到 把show.bin改为show.m4a 使用音频播放软件播放,即可得到flag
- HTML基础复习2
6.表格 6.1建立表格: 表格由<table></table>标签来定义 每行由<tr></tr>来定义,每行被分割为若干单元格,由<td> ...
- 利用JavaUDPSocket+多线程模拟实现一个简单的聊天室程序
对Socket的一点个人理解:Socket原意是指插座.家家户户都有五花八门的家用电器,但它们共用统一制式的插座.这样做的好处就是将所有家用电器的通电方式统一化,不需要大费周章地在墙壁上凿洞并专门接电 ...
- nfs samba文件共享服务
(注意:实验之前强关闭selinux和防火墙) 一丶nfs ① 1.服务端 启动服务 systemctl start nfs.service 配置文件 vim /etc/exports share ...
- 解决PHP无法监听9000端口问题/502错误解决办法
问题背景 配置nginx+php服务的时候,发现网站能打开html,打开php文件就显示502,一般这个是php没启动啊啥的导致不能正常解析php文件. 原因分析 因为nginx解析php文件是交给f ...
- 使用 IPset 进行端口敲门
端口敲门(Port knocking)技术,即服务通过动态的添加 iptables 规则来隐藏系统开启的服务,使用自定义的一系列序列号来「敲门」,使系统开启需要访问的服务端口,才能对外访问.不使用时, ...
- Linux进程内存用量分析之堆内存篇
https://mp.weixin.qq.com/s/a6mLMDinYQGUSaOsGYCEaA 独家|Linux进程内存用量分析之堆内存篇 姬晨烜 58技术 2019-12-06 导语 本文将介绍 ...
- Set、Map的区别
应用场景Set用于数据重组,Map用于数据储存Set: (1)成员不能重复(2)只有键值没有键名,类似数组(3)可以遍历,方法有add, delete,hasMap:(1)本质上是健值对的集合,类似集 ...