当前位置:网站首页>Trie数-字典树
Trie数-字典树
2022-07-04 04:24:00 【sheep.ice】
一、前言
字典树是一个比较神奇的东西。试想如果我们要用程序去存一些字符串,但是相同的字符不能放在不同的空间里面,比如有两个字符串abc,abf,我们发现ab是相同的,就需要我们把他们存在一个数组空间?我们应该怎么做到呢?再来就是为什么叫字典树呢,其实很形象的说明了他的存储方式,就是字典。我们在查字典的时候,都会先查一个单词的首字母,然后在对应的地方继续依次查后面的字母。也就是我们可以利用数组完成这样的存储
但是由于一般数组的空间有限,字典树会占据很多的空间,一个abc就占用了3个单位空间,所以在用的时候是需要注意一下数据范围,是否能够不爆空间!
二、相关操作
①前期变量定义

字典树需要一个二维数组空间,叫做son,为什么这么称呢。因为我们整个树的根节点我们用idx=0来表示。这个点是整个树的头,他有无数的儿子,儿子又有无数的儿子。所以我们亲切的称后续的节点为一个儿子
而son的定义其实就是每一个x都会对应有y个儿子,无论我们是插入操作还是查询操作,为了满足不浪费多余的空间,我们都需要进行首先的判断,作为第x的父亲是否已经存在y这个节点,如果不存在,就给他一个儿子,如果存在,就一视同仁为一个儿子。
②插入一个字符串
假设我们树中的字符串全是小写字母,那我们的儿子其实只可能有26个,所以在开数组的时候就可以开: int s o n [ N ] [ 26 ] son[N][26] son[N][26],而我们后面的例题主要以这个为主。

上面我觉得插入讲得比较清楚了,所以直接贴一个代码好了
void insert(string ss) {
int sz = ss.size();
int p = 0;
for(int i = 0; i < sz; i ++ ) {
int u = ss[i] - 'a';
//如果没有这个儿子就给他一个儿子
if(son[p][u] == 0) son[p][u] = ++idx;
//不管有没有儿子,p指针都会朝向儿子或者新建点走
//一旦p走向新建的点,其实就代表后面的所有点都是新建的
p = son[p][u];
}
}
③查询一个字符串
查询其实和构建是差不多的,就是看我们要查询的字符串是否能够完全的走完构建好的字符串,至于查询,结合后面的题目,大家可以理解,直接贴一个小小的代码。
int query(string ss) {
int sz = ss.size();
int p = 0;
for(int i = 0; i < sz; i ++ ) {
int u = ss[i] - 'a';
if(son[p][u] == 0) return 0;
p = son[p][u];
}
return cnt[p];
}
三、相关题目
题目一

上面的题目就是比较经典的,查询字串出现次数的题目,在我们构建树的时候,我们另外开一个cnt数组,记录一个字符串最后那个字母所在的位置出现了多少个就能解决这个题目了。可以直接看一下完整的代码。
完整AC代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100005;
int son[N][26], cnt[N], idx;
void insrt(string ss) {
int sz = ss.size();
int p = 0;
for(int i = 0; i < sz; i ++ ){
int u = ss[i] - 'a';
if(son[p][u] == 0) son[p][u] = ++ idx;
p = son[p][u];
}
cnt[p] ++ ;
}
int query(string ss) {
int sz = ss.size();
int p = 0;
for(int i = 0; i < sz; i ++ ) {
int u = ss[i] - 'a';
if(son[p][u] == 0) return 0;
p = son[p][u];
}
return cnt[p];
}
int main() {
int n;
cin >> n;
while (n -- ) {
string op, in;
cin >> op >> in;
if(op == "I") {
insrt(in);
}
else {
cout << query(in) << endl;
}
}
return 0;
}
题目二
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kVxj0Ul6-1656845350472)(C:/Users/0604520/AppData/Roaming/Typora/typora-user-images/image-20220703165405990.png)]
这个题目比较的好玩,其实这个题目就是在表述一个二叉树,具体的思路如图解

我们都知道一个二进制数异或起来,相同为0,不同为1,那其实就是再告诉我们,我们在不断建树的过程中,可以用待插入元素,与树中的元素比较,每次去看相同位下有没有和本身不同位的儿子,如果有的话,我们就可以忘那个儿子的路径走。
比如下图:

依次插入5,3,4并且寻找最大异或的元素,
再插入4的时候,先寻找最大异或,我们发现4的二进制是100
对于1这一位,先找有没有0儿子,恰好3的第一位为0,一次类推,他和3抑或能够得到最大的异或值7(111);
完整AC代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100050, M = 31 * N;
//因为儿子只可能有0,1两个选项
int son[M][2], idx = 0;
void insert(int num) {
int p = 0;
//体重说最多有31位
for(int i = 30; i >= 0; i -- ) {
int u = (num >> i) & 1;
if(son[p][u] == 0) son[p][u] = ++idx;
p = son[p][u];
}
}
int query(int num) {
int p = 0, ret = 0;
for(int i = 30; i >= 0; i -- ) {
int u = (num >> i) & 1;
//如果有不同的儿子
if(son[p][!u] != 0) {
ret = ret * 2 + !u;
p = son[p][!u];
}
//如果没有不同的儿子
else {
ret = ret * 2 + u;
p = son[p][u];
}
}
return ret;
}
int main() {
int m, num;
cin >> m;
int ans = 0;
while (m -- ) {
cin >> num;
insert(num);
ans = max(num ^ query(num), ans);
}
cout << ans << endl;
return 0;
}
边栏推荐
- 自动化测试selenium基础篇——webdriverAPI
- 【MATLAB】MATLAB 仿真 — 低通高斯白噪声
- 附件一:202x年xxx攻防演习授权委托书
- Zhongke Panyun - 2022 Guangxi reverse analysis ideas
- appliedzkp zkevm(11)中的EVM Proof
- @Feignclient comments and parameters
- 红队视角下的防御体系突破之第一篇介绍、阶段、方法
- 2022 Guangdong provincial competition - code information acquisition and analysis flag
- Flutter ‘/usr/lib/libswiftCore.dylib‘ (no such file)
- 我们认为消费互联网发展到最后,依然会局限于互联网行业本身
猜你喜欢

Zhongke Panyun - module a infrastructure setting and safety reinforcement scoring standard

PostgreSQL 正式超越 MySQL,这家伙也太强了吧!

电子元器件商城与数据手册下载网站汇总

在代码中使用度量单位,从而生活更美好

Zhongke panyun-2022 Guangdong Trojan horse information acquisition and analysis

分享一些我的远程办公经验

Test cs4344 stereo DA converter

如何构建属于自己的知识引擎?社群开放申请

qt下开发mqtt的访问程序

Fault analysis | mongodb 5.0 reports an error, and the legal instruction solves it
随机推荐
National vocational college skills competition (secondary vocational group) network security competition questions - Analysis
EVM proof in appliedzkp zkevm (11)
【MATLAB】MATLAB 仿真数字带通传输系统 — QPSK 和 OQPSK 系统
拼夕夕二面:说说布隆过滤器与布谷鸟过滤器?应用场景?我懵了。。
【MATLAB】MATLAB 仿真 — 模拟调制系统 之 AM 调制过程
Kivy tutorial 07 component and attribute binding implementation button button click to modify the label component (tutorial includes source code)
Maui introductory tutorial series (5.xaml and page introduction)
附件五:攻击过程简报.docx
Detailed comparison of Hynix emmc5.0 and 5.1 series
【MATLAB】MATLAB 仿真数字基带传输系统 — 数字基带传输系统
测试 CS4344 立体声DA转换器
YoloV6实战:手把手教你使用Yolov6进行物体检测(附数据集)
令人头痛的延时双删
Headache delayed double deletion
分享一些我的远程办公经验
appliedzkp zkevm(11)中的EVM Proof
【MATLAB】MATLAB 仿真模拟调制系统 — VSB 系统
练习-冒泡排序
6-5 vulnerability exploitation SSH weak password cracking and utilization
Correct the classpath of your application so that it contains a single, compatible version of com.go