Trie字典树(超详细!!!)
介绍
字典树,也称Trie、字母树,指的是某个字符串集合对应的形如下图的有根树。树的每条边上对应有恰好一个字符,每个顶点代表从根到该节点的路径所对应的字符串(将所有经过的边上的字符按顺序连接起来)。有时我们也称Trie上的边为转移,顶点为状态。
流程
初始化
一棵空Trie仅包含一个根节点,该点的字符指针均指向空。
插入
当需要插入一个字符串S时,我们令一个指针P起初指向根节点。然后,依次扫描S中的每个字符 c :
1.若P的c字符指针指向一个己经存在的节点Q,则令P=Q。
2.若P的c字符指针指向空,则新建一个节点Q ,令P的 c 字符指针指向Q,然后令P=Q。 当S中的字符扫描完毕时,在当前节点P上标记它是一个字符串的末尾。
查询
当需要查询一个字符串S在Trie中是否存在时,我们令一个指针P起初指向根节点,然后依次扫描S中的每个字符c :
1.若P的c字符指针指向空,则说明S没有被插入过Trie ,结束查询。
2.若P的c字符指针指向一个已经存在的节点Q,则令P=Q 。
当S中的字符扫描完毕时,若当前节点P被标记为一个字符串的末尾,则说明S 在 Trie 中存在,否则说明S没有被插入过Trie。
在上图所示的例子中,需要插入和查询的字符串都由小写字母构成,所以Trie 的每个节点具有 26个字符指针,分别为a到z。上图展示了在一棵空 Trie中依次插入 " cab " " cos " " car " " cat " " cate"和"rain"后的Trie 的形态,灰色标记了单词的末尾节点。
可以看出在Trie 中,字符数据都体现在树的边(指针)上,树的节点仅保存一些额外信息,例如单词结尾标记等。其空间复杂度是O ( NC ) ,其中 N 是节点个数, C是字符集的大小。
初始化
.int ch[N][Z]; //Z为字符集大小
.bool bo[N];
//若bo=true则表示从根到该点经过的边上字母组成的字符串是实际字符串集合中的元素
现在要对一个字符集为小写英文字母的Trie插入一个字符串S:
.void insert(char *s) { //char *s表示一个字符数组
. int len = strlen(s);
. int u = ; //1为根节点
. for(int i = ; i < len; ++i){
. int c = s[i] - 'a';
. if(!ch[u][c])
. ch[u][c] = ++tot; //若不存在这条边则要新建一个节点与转移边
. u = ch[u][c]; //tot为总点数
. }
. bo[u] = true;
. //在串的结尾处将bo赋值,表示它代表一个实际字符串集合中的元素
.}
查询一个字符串S是否是给定字符串集合中某个串的前缀:
.bool find(char s[]) {
. int len = strlen(s);
. int u = ;
. for(int i = ; i < len; ++i){
. int c = s[i] - 'a';
. if(!ch[u][c]) return false;
. u = ch[u][c];
. }
. return true;
.}
【例题1】Phone List(信息学奥赛一本通 1471)
【题目描述】
给定 n 个长度不超过 10 的数字串,问其中是否存在两个数字串 S,T,使得 S 是 T 的前缀,多组数据。
【输入】
第一行一个整数 T,表示数据组数。 对于每组数据,第一行一个数 n,接下来 n 行输入 n 个数字串。
【输出】
对于每组数据,若存在两个数字串 S,T,使得 S 是 T 的前缀,则输出 NO ,否则输出 YES 。 请注意此处结果与输出的对应关系!
【输入样例】
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
【输出样例】
NO
YES
【例题2】The XOR Largest Pair(信息学奥赛一本通 1472)
【题目描述】
在给定的 N 个整数 A1,A2,…, AN 中选出两个进行异或运算,得到的结果最大是多少?
【输入】
第一行一个整数 N。 第二行 N 个整数 Ai。
【输出】
一个整数表示答案。
【输入样例】
5
2 9 5 7 0
【输出样例】
14
思路:
对于每个 i ( 1<=i <= N ) ,我们希望找到一个 j ( 1 <=j < i ) ,使Ai xor Aj最大。
我们可以把每个整数看作长度为 32 的二进制 01 串(数值较小时在前边补 0 ),并且把A1~Ai-1对应的 32 位二进制串插入一棵 Trie 树(最低二进制位为叶子节点)。接下来,对于 Ai 对应的 32 位二进制串,我们在 Trie 中进行一次与查询类似的过程,每一步都尝试沿着“与 Ai 的当前位相反的字符指针”向下访问。若“与 Ai 的当前位相反的字符指针”指向空节点,则只好访问与 Ai 当前位相同的字符指针。根据 xor 运算“相同得 0 ,不同得 1 ”的性质,该方法即可找出与 A i做 xor 运算结果最大的Aj。
Trie字典树(超详细!!!)的更多相关文章
- 踹树(Trie 字典树)
Trie 字典树 ~~ 比 KMP 简单多了,无脑子选手学不会KMP,不会结论题~~ 自己懒得造图了OI WIKI 真棒 字典树大概长这么个亚子 呕吼真棒 就是将读进去的字符串根据当前的字符是什么和所 ...
- 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)
萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...
- Trie字典树 动态内存
Trie字典树 #include "stdio.h" #include "iostream" #include "malloc.h" #in ...
- 算法导论:Trie字典树
1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tr ...
- 标准Trie字典树学习二:Java实现方式之一
特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! 系列文章: 1. 标准Trie字典树学习一:原理解析 2.标准T ...
- 817E. Choosing The Commander trie字典树
LINK 题意:现有3种操作 加入一个值,删除一个值,询问pi^x<k的个数 思路:很像以前lightoj上写过的01异或的字典树,用字典树维护数求异或值即可 /** @Date : 2017- ...
- C++里创建 Trie字典树(中文词典)(一)(插入、遍历)
萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...
- 数据结构 -- Trie字典树
简介 字典树:又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种. 优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高. 性质: 1. 根节 ...
- Trie字典树详解
今天上午省选字符串......只会KMP.连hash都不会的我被大佬虐惨了......于是我要发奋图强学习字符串,学习字符串当然就要从Trie树这种可爱的数据结构开始啦!!! 一.什么是Trie树?? ...
随机推荐
- POJ 1306 暴力求组合数
Combinations Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11049 Accepted: 5013 Des ...
- Luogu P3879 【[TJOI2010]阅读理解】
前言: 这个题一直有个疑问,最多一千行,每行五千字$1000\times5000=5e6$ $5e6\times26\times4\div1024\div1024\approx496Mb>125 ...
- golang学习笔记----并发
并发模型 并发目前来看比较主流的就三种: 多线程:每个线程一次处理一个请求,线程越多可并发处理的请求数就越多,但是在高并发下,多线程开销会比较大. 协程:无需抢占式的调度,开销小,可以有效的提高线程的 ...
- Centos7/Ubuntu 初始化硬盘分区、挂载
刚刚在腾讯云买了一台服务器,刚买的服务器的数据盘都是需要自己来分区的,下面就记录一下操作. 通过命令fdisk-l查看硬盘信息 可以看到有两块硬盘/dev/vda和/dev/vdb,启动vda是系统盘 ...
- java设计模式结构型模式
结构型模式: – 核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结 构,用来解决更大的问题 分类: • 适配器模式.代理模式.桥接模式. 装饰模式.组合模式.外观模式.享元模式 结构型模式 ...
- Blend 设置一个圆形的按钮
原文:Blend 设置一个圆形的按钮 1)画一个圆形 右击构成控件 3)选择button 当然如果想做成别的控件 都可以 4)我们有了一个button 5)做动画 6)定义触发器 7)定义事件 效果
- 把JSON数据格式转换为Python的类对象
JOSN字符串转换为自定义类实例对象 有时候我们有这种需求就是把一个JSON字符串转换为一个具体的Python类的实例,比如你接收到这样一个JSON字符串如下: {"Name": ...
- wc.exe个人项目
1.GitHub项目 https://github.com/Littlehui3/wc 2.用时表格 PSP2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min) Plannin ...
- 【剑指 offer】数组中重复的数字 -- PHP 实现
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
- 【Java_基础】Java中强制类型转换
首先,狭义上的强制类型转换指的是引用类型,且是父类向子类转换,这种转换只牵扯到引用名义类型的转换,具体的对象内存没有发生一点变化. 而基本类型的转换与此不同,其数据确实发生了变化.如果是基本类型和其包 ...