当前位置: 首页 > news >正文

37.字典树

一、简介

字典树,英文名为 Trie,又称单词查找树,它是一种特殊的数据结构,用于处理字符串的一种树形结构。顾名思义,字典树在使用的时候类似于在字典中查单词,从第一个字符开始遍历,在 Trie 中按层往下查找,查找效率可以达到 O(n)O(n)O(n)nnn 为查找字符串的长度。

Trie 的功能非常强大,可以支持对于字符串的各种操作,包括插入、删除、修改和查询操作。Trie一边用来处理字符串的快速检索,字符串的快速排序与去重,文本的词频统计等问题。Trie 的构建利用字符串的公共前缀,逐层建立起一棵多叉树。下图是一个基础的例子:

在这里插入图片描述

从这张图中我们不难看出 Trie 具有以下特点:

  • Trie 的根结点上不存储字符,其余结点上存且只存一个字符。
  • 从根结点出发,到某一结点上经过的字符,即是该结点对应的前缀。
  • 每个结点的孩子结点存储的字符各不相同。
  • Trie 牺牲空间来换取时间,当数据量很大时,会占用很大空间。如果字符串均由小写字母组成,则每个结点最多会有 262626 个孩子结点,则最多会有 26n26n26n 个用于存储的结点,nnn 为字符串的长度总和。

二、基本运用

任何一个良好的数据结构都应该满足增加、删除、修改和查询四大功能,下面我们从这些方面来讲解。我们假设题目的需求是:求出当前所查询的字符串是多少前面所给字符串的前缀。我们以此为基础来介绍字典树的基本构造方法,需要注意对于每道题目各种功能的实现也略有不同。

1.初始化

  • 在一开始需要将 trie 数组初始化为 −1-11,表示该节点从未使用过。
  • tot 变量用于表示整个字典树中存在多少节点。
void init()
{memset(trie, -1, sizeof(trie));memset(sum, 0, sizeof(sum));tot = 0;
}

2.插入

  • 在插入字符串的时候,我们首先从字典树的根节点(编号为 000)开始。
  • 遍历整个字符串,因为字典树以数组的方式存储,所以需要通过某种方式将符号对应到数字。这里假设所有字母都是小写,因此使用了 str[i]-'a' 的方式进行转换。
  • trie[p][ch] == -1 表示该节点还没有被创建过,所以新建节点 ++tot
  • p = trie[p][ch] 表示为进入当前字符串前 iii 个字符的对应子节点。
  • sum[p]++ 用于记录以当前这样的前 iii 个字符为前缀的字符串有多少个
void insert(string str)
{ll len = str.size(), p = 0;for(ll i = 0; i < len; i++){ll ch = str[i] - 'a';if(trie[p][ch] == -1)trie[p][ch] = ++tot;p = trie[p][ch];sum[p]++;}
}

3.删除

  • 因为 tot 的数量已经改变,所以最好不好直接删除节点
  • 我们只需要将 sum[p] 的计数情况做一些修改即可
void erase(string str)
{ll len = str.size(), p = 0;for(ll i = 0; i < len; i++){ll ch = str[i] - 'a';if(trie[p][ch] == -1)return;p = trie[p][ch];sum[p]--;}
}

4.查询

  • 根据字符串在字典树中的位置依次递推直到结尾,最后返回当前的计数情况即可。
ll search(string str)
{ll len = str.size(), p = 0;for(ll i = 0; i < len; i++){ll ch = str[i] - 'a';if(trie[p][ch] == -1)return 0;p = trie[p][ch];}return sum[p];
}

三、作业

1.黄题

P1481 魔族密码

P2580 于是他错误的点名开始了

P8306 【模板】字典树

UVA11362 Phone List

2.绿题

CF706D Vasiliy’s Multiset

http://www.dtcms.com/a/316564.html

相关文章:

  • Redis集群模式下确保Key在同一Slot的实现方法
  • 按位运算 - C++
  • Velero 简介和部署
  • Linux进程信号——初步认识信号、信号的产生
  • 《UE教程》第一章第六回——迁移独立项目(资源)
  • IAR软件中变量监控的几种方法
  • 如何在 FastAPI 中优雅处理后台任务异常并实现智能重试?
  • Wireshark安装过程 Npcap Setup: Failed to create the npcap service: 0x8007007e.
  • 信息系统项目管理中的沟通管理实战精解
  • 智慧能源场景设备缺陷漏检率↓76%:陌讯多模态融合检测方案实战解析
  • SpringCloud学习------Gateway详解
  • Claude Code 完整指南:入门到应用
  • Qt事件系统学习笔记
  • 嵌入式软件架构设计之七:双机通信及通信协议之字符串协议
  • 大语言模型安全攻防:从提示词注入到模型窃取的全面防御浅谈
  • 与功能包相关的指令ros2 pkg
  • 女性成长赛道:现状与发展趋势|创客匠人
  • NumPy 中的取整函数
  • 如何在Android设备上删除多个联系人(3种方法)
  • Java项目:基于SSM框架实现的公益网站管理系统【ssm+B/S架构+源码+数据库+毕业论文+答辩PPT+远程部署】
  • 解锁高效敏捷:2025年Scrum项目管理工具的核心应用解析
  • 智慧社区物业管理平台登录流程全解析:从验证码到JWT认证
  • 关于熵减 - 双线线圈
  • 前端性能测试:从工具到实战全解析
  • 类内部方法调用,自注入避免AOP失效
  • Flutter 国际化
  • OpenSpeedy绿色免费版下载,提升下载速度,网盘下载速度等游戏变速工具
  • spring boot 加载失败 异常没有曝漏出来
  • 基于Java AI(人工智能)生成末日题材的实践
  • 2. JS 有哪些数据类型