字典树学习笔记
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
友情提示:看这篇文章一定要用暗色模式(键在右上角)
字典树(Trie)简介
又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
——百度百科
字典树是一种树形结构,用于用于统计,排序和保存大量的字符串。
\(\qquad\qquad\qquad\qquad\qquad\qquad\qquad\)
字典树概念
假设现在有六个字符串,分别是:“ac”、“ace”、“acu”、“wa”、“who”、“pc”,用这几个字符串构造Trie
\(\qquad\qquad\qquad\qquad\qquad\qquad\qquad\)
那字典树是如何运作的呢?
1.查找
- 假设我们要查找“acu”这个字符串,我们需要顺着树边往下找
\(\qquad\qquad\qquad\qquad\qquad\qquad\)
如果最终的那个点是灰色(该节点是一个字符串结束的位置),查找就完成了,该字符串存在
- 再假设我们要查找“what”这个字符串
\(\qquad\qquad\qquad\qquad\qquad\qquad\)
当找到“a”时,发现没有“a”,这时可以直接返回没找到,不用继续找下去了!
2.插入(建树)
插入字符串的思路很简单,假设现在我们要在一棵空Trie中按顺序插入“ac”、“ace”、“acu”、“wa”、“who”、“pc”
0.插入前
\(\qquad\qquad\qquad\qquad\qquad\qquad\qquad\)
1. 插入“ac”
我们发现当前节点(root)没有“a”,于是新建一个节点“a”;同样的,我们也在“a”下新建一个节点“c”,“c”标记为灰色
\(~~~~~~~~~~~~~~\)\(~~~~~~~~\)
2. 插入“ace”
我们发现当前节点(root)有“a”,于是经过节点“a”;同样的,我们也经过“a”节点“c”,“c”标记为灰色;我们发现当前节点(“c”)没有“e”,于是新建一个节点“e”,“e”标记为灰色
\(~~~~~~~~~~~~~~\)\(~~~~~~~~\)$$\scriptsize\color{grey}{经过节点a~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~经过节点c}$$
\(\qquad\qquad\qquad\qquad\qquad\qquad\qquad\)
3. 插入“acu”
我们发现当前节点(root)有“a”,于是经过节点“a”;同样的,我们也经过“a”节点“c”,“c”标记为灰色;我们发现当前节点(“c”)没有“u”,于是新建一个节点“u”,“u”标记为灰色
\(~~~~~~~~~~~~~~\)\(~~~~~~~~\)
\(\qquad\qquad\qquad\qquad\qquad\qquad\qquad\)
4. 插入“wa”
我们发现当前节点(root)没有“w”,于是新建一个节点“w”;同样的,我们也在“w”下新建一个节点“a”,“a”标记为灰色
\(~~~~~~~~~~~~~~\)\(~~~~~~~~\)
5. 插入“who”
我们发现当前节点(root)有“w”,于是经过节点“w”;我们发现当前节点(“w”)没有“h”,于是新建一个节点“h”;同样的,我们发现当前节点(“w”)没有“o”,于是也新建一个节点“o”,“o”标记为灰色
\(~~~~~~~~~~~~~~\)\(~~~~~~~~\)
\(\qquad\qquad\qquad\qquad\qquad\qquad\qquad\)
6. 插入“pc”
我们发现当前节点(root)没有“p”,于是新建一个节点“p”;同样的,我们也在“p”下新建一个节点“c”,“c”标记为灰色
\(~~~~~~~~~~~~~~\)\(~~~~~~~~\)
字典树实现
点击查看题目
题目描述
给定 \(n\) 个模式串 \(s_1, s_2, \dots, s_n\) 和 \(q\) 次询问,每次询问给定一个文本串 \(t_i\),请回答 \(s_1 \sim s_n\) 中有多少个字符串 \(s_j\) 满足 \(t_i\) 是 \(s_j\) 的前缀。
一个字符串 \(t\) 是 \(s\) 的前缀当且仅当从 \(s\) 的末尾删去若干个(可以为 0 个)连续的字符后与 \(t\) 相同。
输入的字符串大小敏感。例如,字符串 Fusu
和字符串 fusu
不同。
输入格式
本题单测试点内有多组测试数据。
输入的第一行是一个整数,表示数据组数 \(T\)。
对于每组数据,格式如下:
第一行是两个整数,分别表示模式串的个数 \(n\) 和询问的个数 \(q\)。
接下来 \(n\) 行,每行一个字符串,表示一个模式串。
接下来 \(q\) 行,每行一个字符串,表示一次询问。
输出格式
按照输入的顺序依次输出各测试数据的答案。
对于每次询问,输出一行一个整数表示答案。
样例 #1
输入
3
3 3
fusufusu
fusu
anguei
fusu
anguei
kkksc
5 2
fusu
Fusu
AFakeFusu
afakefusu
fusuisnotfake
Fusu
fusu
1 1
998244353
9
输出
2
1
0
1
2
1
提示
对于全部的测试点,保证 \(1 \leq T, n, q\leq 10^5\),且输入字符串的总长度不超过 \(3 \times 10^6\)。输入的字符串只含大小写字母和数字,且不含空串。
std 的 IO 使用的是关闭同步后的 cin/cout,本题不卡常。
code
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |