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自动机模版题咯 注意一般情况 ...
随机推荐
- LR参数
一.LR函数 : lr_start_transaction: 为性能分析标记事务的开始 lr_end_transaction: 为性能分析标记事务的结束:事务名称与事务开始时保持一致 lr_ren ...
- 屏蔽每分钟SSH尝试登录超过10次的IP
屏蔽每分钟SSH尝试登录超过10次的IP 方法1:通过lastb获取登录状态: #!/bin/bash DATE=$(date +"%a %b %e %H:%M") #星期月天时分 ...
- C#使用ODP.NET连接oracle数据库
ODP.NET:Oracle Data Provider for .NET 分为三种: ODP.NET, Managed Driver 不需要安装oracle客户端 ODP.NET,Unmanaged ...
- SAP下载文档为乱码
通过事物WE60下载的文档为乱码,主要原因是编码格式的不匹配,通常默认的编码格式为ANSI编码,那么我们需要将源码的编码格式转换成UTF-8,这样问题可以解决了. 附:编码格式介绍 不同的国家和地 ...
- [Usaco2016 Dec]Counting Haybales
原题链接https://www.lydsy.com/JudgeOnline/problem.php?id=4747 先将原数组排序,然后二分查找即可.时间复杂度\(O((N+Q)logN)\). #i ...
- mysql 设置外键约束时如何删除数据
Mysql中如果表和表之间建立的外键约束,则无法删除表及修改表结构 解决方法是在Mysql中取消外键约束: SET FOREIGN_KEY_CHECKS=0; 然后将原来表的数据导出到sql语句,重新 ...
- 墓碑机制与 iOS 应用程序的生命周期
① 应用程序的状态 iOS 应用程序一共有 5 种状态: Not running:应用未运行 Inactive:应用运行在 foreground 但没有接收事件 Active:应用运行在 foregr ...
- Compile-time Dependency Injection With Go Cloud's Wire 编译时依赖注入 运行时依赖注入
Compile-time Dependency Injection With Go Cloud's Wire - The Go Blog https://blog.golang.org/wire Co ...
- memory barrier 内存屏障 编译器导致的乱序
小结: 1. 很多时候,编译器和 CPU 引起内存乱序访问不会带来什么问题,但一些特殊情况下,程序逻辑的正确性依赖于内存访问顺序,这时候内存乱序访问会带来逻辑上的错误, 2. https://gith ...
- python 10函数式编程
函数式编程 函数是Python内建支持的一种封装, ...