数据结构 - Tire 树
文章目录
- 一、Tire 树
- 1. Tire 树介绍
- 2. 优缺点及性质
- 3. 具体实现可见例题 Tire 字符串统计
- 二、Tire 树例题——Tire 字符串统计
- 具体实现
- 1. 实现过程
- 2. 代码注解
- 3. 实现代码
- 三、Tire 树例题——最大异或对
- 具体实现
- 0. 暴力做法
- 1. 实现思路
- 2. 实现代码
一、Tire 树
1. Tire 树介绍
- Tire 树 又称单词查找树,是一种树形结构,是一种哈希树的变种。
- Tire 树是一种能够快速存储和查找一组字符串集合的数据结构,是以空间换时间,利用字符串的前缀来降低查询时间。
- 与二叉树不同,Tire 树有 26 子节点对应 26 个字母,根节点不包含字符串,从根节点到某个节点,经过的字符连起来的字符串就是对应的字符串。当储存结束一个字符串后,尾节点会产生一个标记,表示当前字符串已经结束了。
- 典型应用:用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
- 如下图就是一棵由字符串 abcdef,abdef,aced,bcdf,bcfc,bcff,cdaa,组成的 Tire 树:
2. 优缺点及性质
- 优点:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
- 缺点:空间复杂度比较大。
- 优化:我们可以用链表来动态开辟空间,达到空间上利用率的最大化。
- 性质:
- (1)根结点不包含字符,其他的每一个节点只包含一个字符。
- (2)从根结点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串(假如某个节点为一个字符串的结尾,对其打个标记即可)。
- (3)每个节点的所有子节点包含的字符都不相同。
3. 具体实现可见例题 Tire 字符串统计
二、Tire 树例题——Tire 字符串统计
题目描述
维护一个字符串集合,支持两种操作:
I x
向集合中插入一个字符串 x;
Q x
询问一个字符串在集合中出现了多少次。
共有 N 个操作,所有输入的字符串总长度不超过 1e5,字符串仅包含小写英文字母。
输入格式
第一行包含整数 N,表示操作数。
接下来 N 行,每行包含一个操作指令,指令为 I x
或 Q x
中的一种。
输出格式
对于每个询问指令 Q x
,都要输出一个整数作为结果,表示 x 在集合中出现的次数。
每个结果占一行。
数据范围
1 ≤ N ≤ 2∗1e4
输入样例
5
I abc
Q abc
Q ab
I ab
Q ab
输出样例
1
0
1
具体实现
1. 实现过程
- Tire 树的插入和查询功能的实现。
- (1)
I x
向集合中插入一个字符串 x。
void insert(char str[])
{int p=0;for(int i=0;str[i];i++) {int u=str[i]-'a';if(!son[p][u]){idx++;son[p][u]=idx; }p=son[p][u];}cnt[p]++;
}
- (2)
Q x
询问一个字符串在集合中出现了多少次。
int query(char str[])
{int p=0;for(int i=0;str[i];i++) {int u=str[i]-'a';if(!son[p][u]){return 0;}else{p=son[p][u];}}return cnt[p];
}
2. 代码注解
- int son[N][26]; 表示树当中每个点的所有子节点。
- int cnt[N]; 表示以当前这个点结尾的单词有多少个。
- int idx; 表示当前用到了哪个下标。这里需要注意:下标是 0 的点,既是根节点,又是空节点。
- C++ 字符串结尾是 \0 ,因此 str[i] 可以判断字符串是否走到结尾。
- int u=str[i]-‘a’; 将小写字母 a~z ,映射成数字 0~25。
3. 实现代码
#include <bits/stdc++.h>
using namespace std;const int N=100010;
int son[N][26];
int cnt[N];
char str[N];
int idx;
void insert(char str[])
{int p=0;for(int i=0;str[i];i++) {int u=str[i]-'a';if(!son[p][u]){idx++;son[p][u]=idx;}p=son[p][u];}cnt[p]++;
} int query(char str[])
{int p=0;for(int i=0;str[i];i++) {int u=str[i]-'a';if(!son[p][u]){return 0;}p=son[p][u];}return cnt[p];
}int main()
{int n;cin>>n;while(n--){char op[2];scanf("%s%s",op,str);if(op[0]=='I'){insert(str);}else{cout<<query(str)<<endl;}}system("pause");return 0;
}
三、Tire 树例题——最大异或对
题目描述
在给定的 N 个整数 A1,A2……AN 中选出两个进行 xor(异或)运算,得到的结果最大是多少?
输入格式
第一行输入一个整数 N。
第二行输入 N 个整数 A1~AN。
输出格式
输出一个整数表示答案。
数据范围
1 ≤ N ≤ 1e5
0 ≤ Ai < 2的31次方
输入样例
3
1 2 3
输出样例
3
具体实现
0. 暴力做法
- 暴力做法通俗易懂,两个 for 循环,相互枚举每一个值,异或,最后答案为其中的最大值。
- 暴力做法虽然易做,但是会出现 超时 问题。
#include <bits/stdc++.h>
using namespace std;const int N=100010;
int n;
int a[N];
int main()
{cin>>n;for(int i=0;i<n;i++){cin>>a[i];}int res=0;for(int i=0;i<n;i++){for(int j=0;j<n;j++){res=max(res,a[i]^a[j]);}}cout<<res<<endl;system("pause"); return 0;
}
1. 实现思路
- 首先,需要搞清楚 异或操作。
- 如果 A = 1101 ,B = 0111,那么 A ^ B = 1010。详细讲解请见 基础算法-位运算
- 对暴力做法进行优化,使其满足时间限制。
- 由异或操作的计算公式可知,我们只需要先遍历每一个数,然后根据遍历的数的对应二进制形式,选取一个尽可能二进制形式每一位都不同的数字,得到该数字的最大异或值,最后再选举最大的异或值。在得到每一个数字的最大亦或值的选取过程就是一个 Tire 数。
- 举例说明:
2. 实现代码
#include <bits/stdc++.h>
using namespace std;const int N = 100010, M = 3100010;
int n;
int a[N], son[M][2], idx;void insert(int x)
{int p = 0;for (int i = 30; i >= 0; i -- ){int &s = son[p][x >> i & 1];if (!s) {idx ++;s = idx;}p = s;}
}int search(int x)
{int p = 0, res = 0;for (int i = 30; i >= 0; i -- ){int s = x >> i & 1;if (son[p][!s]){res += 1 << i;p = son[p][!s];}else {p = son[p][s];}}return res;
}int main()
{cin >> n;for (int i = 0; i < n; i ++ ){cin >> a[i];insert(a[i]);}int res = 0;for (int i = 0; i < n; i ++ ){res = max(res, search(a[i]));}cout << res << endl;system("pause");return 0;
}
数据结构 - Tire 树相关推荐
- 数据结构--Tire树
实现一个Trie树 一.Trie树的基本操作 二.代码实现 一.Trie树的基本操作 (1) 插入字符串 (2) 搜索目标字符串 (3) 搜索以目标字符串为前缀的情况是否存在 二.代码实现 class ...
- php tire树,Immutable.js源码之List 类型的详细解析(附示例)
本篇文章给大家带来的内容是关于Immutable.js源码之List 类型的详细解析(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 一.存储图解 我以下面这段代码为例子,画 ...
- 数据结构4:Tire树入门
以下来源于百度百科: 在计算机科学中,Trie,又称字典树.单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串). 特点:利用字符串的公 ...
- 字符串匹配数据结构 --Trie树 高效实现搜索词提示 / IDE自动补全
文章目录 1. 算法背景 2. Trie 树实现原理 2.1 Trie 树的构建 2.2 Trie树的查找 2.3 Trie树的遍历 2.4 Trie树的时间/空间复杂度 2.5 Trie 树 Vs ...
- Tire树(字典树-字符串快速查找)
前言 一.Tire树是什么? 二.怎么建立tire树 1.字符串插入Tire树入 2.查找字符串 总结 前言: 最近是在复习基础算法,正好复习到了数据结构,所以写了自己对Tire树的理解,数据结构对我 ...
- tire树的存储和并查集
tire树 tire树又称字典树,是一种能够高效存储和查找字符串集合的数据结构. 图形如下图所示 每个节点表示一个字符串中的字符,从根节点到灰色节点的一条路径表示一个字符串(灰色节点表示是某个单词的结 ...
- tire树代码示例和例题
tire树 [模板]字典树 题目描述 给定 n n n 个模式串 s 1 , s 2 , - , s n s_1, s_2, \dots, s_n s1,s2,-,sn 和 q q q 次询问, ...
- 数据结构显示树的所有结点_您需要了解的有关树数据结构的所有信息
数据结构显示树的所有结点 When you first learn to code, it's common to learn arrays as the "main data struct ...
- 0x16.基本数据结构 — Trie树(字典树)+ A C 自 动 机
目录 用TrieTrieTrie树来处理整数异或问题是真的舒服! 一.TrieTrieTrie树 TrieTrieTrie的基本操作 0.初始化 1.插入 2.检索 二.TrieTrieTrie树例题 ...
最新文章
- js / jquery 零散收集
- 制造型企业如何降低成本提升核心竞争力
- mysql job_MySQL数据传输中dtle 之 job 实现简析-爱可生
- 总分第一!阿里云数据库应用迁移解决方案通过信通院首批最高级评测
- 漫画:什么是优先队列
- AngularJS.js: temple
- Ecere SDK:用于GUI和图形的跨平台工具包
- mycat分布式mysql中间件(自增主键)
- MTK和高通展讯他们平台的主要区别是什么
- adb shell settings(系统服务:settings)
- github项目(重点)
- Java开发环境及其特点
- 我的python初学练习
- Python开源小闹钟
- 亿道丨三防平板丨工业平板丨比消费类平板好在哪?
- Spark Bloom Filter 测试
- hihoCoder1044
- 嵌套交叉验证的一致特征(Consensus features nested cross-validation)
- oracle基础|数据库模型|实体-关系图(E-R图)|什么是一对一、一对多、多对多
- 安装ActivePerl
热门文章
- react-native使用模拟器调试步骤(安卓机)
- 把腾讯搬上云:云服务器 CVM 的半部进化史
- Vitis指南 | Xilinx Vitis 系列(六)
- python3 translate---TypeError: translate() takes exactly one argument (2 given)
- 机试指南练习-第三章
- Linux load average负载量分析与解决思路
- Python基础_第5章_Python中的数据序列
- Matlab之雷达扫描模式配置(附源码)
- 二十四、搜索引擎功能实现(商品部分)
- 74HC595驱动(并转串,fpga与时钟匹配,fpga与外部芯片的连接注意事项)