前缀树

2023-11-13

前缀树的结构

Trie树,又叫字典树、前缀树(Prefix Tree)、单词查找树或键树,是一种多叉树结构。如下图:

 

 
上图是一棵Trie树,表示了关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。

Trie树的基本性质: 

  1. 根节点不包含字符,除根节点外的每一个子节点都包含一个字符。 
  2. 从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。 
  3. 每个节点的所有子节点包含的字符互不相同。 
  4. 从第一字符开始有连续重复的字符只占用一个节点,比如上面的to,和ten,中重复的单词t只占用了一个节点。

前缀树的应用

  1. 前缀匹配 
  2. 字符串检索 
  3. 词频统计 
  4. 字符串排序

 

前缀匹配

前缀单词:in,就是 inn 的前缀单词。如果有十几万条单词,并且每个单词的长度都是5-10以内,这样必定存在大量重复的

字符,因此利用前缀树来求解不仅速度快而且空间复杂度也比较好。 

 

代码实现



public class TrieTools {
	private TrieNode root = new TrieNode();
	/**
	 * 字典树的加入过程
	 */
	public void add(String word) {
		if (word == null)
			return;
		char[] chars = word.toCharArray();
		TrieNode node = root;
		for (char c : chars) {
			// 当前节点的子节点不存在这个字符,子节点添加该字符
			if (!node.children.containsKey(c)) {
				node.children.put(c, new TrieNode());
			}
			// 当前节点的子节点存在这个字符,下一个元素位置在子节点的子节点
			node = node.children.get(c);
			// 字符路过这个结点的次数+1
			node.path++;
		}
		// 以当前结点为结束的字符+1
		node.end++;
	}

	/**
	 * 字典树查询目标单词出现的次数
	 */
	public int get(String word) {
		//排除null情况
		if (word == null)return 0;
			
		 
		char[] chars = word.toCharArray();
		TrieNode node = root;
		//查找单词的最后一个节点,该节点记录了这个单词出现的次数
		for (char c : chars) {
			//如果首字符串不在节点中,返回0
			if (!node.children.containsKey(c))return 0;
			
			node = node.children.get(c);
		}
		return node.end;
	}

	/**
	 * 字典树查询以目标前缀的单词有多少个
	 */
	public int getPre(String word) {
		//排除null情况
		if (word == null)return 0;
			
		char[] chars = word.toCharArray();
		TrieNode node = root;
		//查找单词的最后一个节点,该节点记录了这个字符出现的次数,也就是目标前缀的单词的数目
		for (char c : chars) {
			//如果首字符串不在节点中,返回0
			if (!node.children.containsKey(c))return 0;
			node = node.children.get(c);
		}
		return node.path;
	}
	

	public static void main(String[] args) {
		TrieTools trie = new TrieTools();
		trie.add("a");
		trie.add("ab");
		trie.add("ac");
		trie.add("abc");
		trie.add("acb");
		trie.add("abcc");
		trie.add("aab");
		trie.add("abx");
		System.out.println("单词出现的次数: "+trie.get("abc"));
		System.out.println("目标前缀的单词数: "+trie.getPre("ab"));
	}

}







/**
 * 前缀树结构
 */
public class TrieNode {
	/**
	 * path表示字符路过这个结点的次数(即表示存在以当前结点为前缀的字符有多少个);
	 */
    public int path;
    /**
     * end记录以当前结点为结束的字符有多少个。
     */
    public int end;
    /**
     * 子节点
     */
    HashMap<Character, TrieNode> children=new HashMap<Character, TrieNode>();

 
}

测试结果:

单词出现的次数: 1
目标前缀的单词数: 4
 

 

 

过程步骤:

 

 

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前缀树 的相关文章

  • 带头双向循环链表:一种高效的数据结构

    博客主页 江池俊的博客 收录专栏 数据结构探索 专栏推荐 cpolar C语言进阶之路 代码仓库 江池俊的代码仓库 编译环境 Visual Studio 2022 欢迎大家点赞 评论 收藏 文章目录 一 带头循环双向链表的概念及结构 二 使
  • 算法题-简单系列-04-链表中倒数最后k个结点

    文章目录 1 题目 1 1 快慢指针 1 题目 输入一个长度为 n 的链表 设链表中的元素的值为 ai 返回该链表中倒数第k个节点 如果该链表长度小于k 请返回一个长度为 0 的链表 1 1 快慢指针 代码中的类名 方法名 参数名已经指定
  • 算法设计与实现--贪心篇

    贪心算法 贪心算法是一种在每一步选择中都采取当前状态下最优决策的算法 以期望能够通过一系列局部最优的选择达到全局最优 贪心算法的关键是定义好局部最优的选择 并且不回退 即一旦做出了选择 就不能撤销 一般来说 贪心算法适用于满足以下两个条件的
  • 算法设计与实现--动态规划篇

    什么是动态规划算法 动态规划算法是一种求解复杂问题的方法 通过将原问题分解为相对简单的子问题来求解 其基本思想是将待求解的问题分解为若干个子问题 阶段 按顺序求解子阶段 前一子问题的解 为后一子问题的求解提供了有用的信息 在求解任一子问题时
  • D (1173) : A DS二叉树_合并二叉树

    文章目录 一 题目描述 二 输入与输出 1 输入 2 输出 三 参考代码 一 题目描述 给定两个二叉树 输出这两个二叉树合并后形成的二叉树 依次输出前序遍历 中序遍历 后序遍历 二 输入与输出 1 输入 第一行输入t 表示有t个测试样例 第
  • 数组实现循环队列(增设队列大小size)

    目录 一 前言 1 如何实现循环 2 如何判断队列为空 3 如何判断队列为满 二 循环队列的结构定义 三 循环队列的创建及其初始化 四 入队 五 出队 六 取队头元素 七 取队尾元素 八 循环队列判空 九 循环队列判满 十 循环队列销毁 一
  • C/C++查找算法-----------------------二分查找详解

    二分查找 定义 实例 定义 二分查找也称折半查找 搜索过程从数组的中间元素开始 如果中间元素正好是要查找的元素 则搜索过程结束 如果某一特定元素大于或者小于中间元素 则在数组大于或小于中间元素的那一半中查找 而且跟开始一样从中间元素开始比较
  • 二叉树(接口函数的实现)

    今天继续来分享的是二叉树 我们废话不多说 直接来看下面的几个接口函数 然后我们把他们实现 我们就掌握二叉树的二分之一 今天粉丝破千了 属实有点高兴了 typedef char BTDataType typedef struct Binary
  • 【数据结构】双链表的定义和操作

    目录 1 双链表的定义 2 双链表的创建和初始化 3 双链表的插入节点操作 4 双链表的删除节点操作 5 双链表的查找节点操作 6 双链表的更新节点操作 7 完整代码 嗨 我是 Filotimo 很高兴与大家相识 希望我的博客能对你有所帮助
  • 回溯算法第零篇【递归、搜索与回溯】【回溯算法入门必看】

    本篇文章的目的 1 给小伙伴们对回溯算法中的名词进行解释 2 消除递归的恐惧 回溯是递归的一个分支 给小伙伴们一个建议 整篇文章都要看完 一字不漏 全是干货 注意 分析回溯的思想之前 我们得知道一个关系 递归包含搜索 搜索包含回溯 所以我们
  • 数组对象排序 (arr.sort())

    前端面试题库 面试必备 推荐 地址 前端面试题库 对象排序 arr sort 描述 方法sort 将在原数组上对 数组元素 进行排序 即排序时不创建新的数组副本 如果想按照别的顺序进行排序 就必须提供比较函数 该函数要比较两个值 然后返回一
  • 回溯算法第零篇【递归、搜索与回溯】【回溯算法入门必看】

    本篇文章的目的 1 给小伙伴们对回溯算法中的名词进行解释 2 消除递归的恐惧 回溯是递归的一个分支 给小伙伴们一个建议 整篇文章都要看完 一字不漏 全是干货 注意 分析回溯的思想之前 我们得知道一个关系 递归包含搜索 搜索包含回溯 所以我们
  • LeetCode21. Merge Two Sorted Lists

    文章目录 一 题目 二 题解 一 题目 You are given the heads of two sorted linked lists list1 and list2 Merge the two lists into one sort
  • 数据结构学习笔记(七)搜索结构

    文章目录 1 前言 2 概念 3 静态搜索结构 3 1 静态搜索表 3 2 顺序搜索表 3 2 1 基于有序顺序表和顺序搜索和折半搜索 4 二叉搜索树
  • Leetcode 45 跳跃游戏 II

    题意理解 给定一个长度为 n 的 0 索引 整数数组 nums 初始位置为 nums 0 每个元素 nums i 表示从索引 i 向前跳转的最大长度 还是从初始坐标i 0的位置到达最后一个元素 但是问题不是能不能跳到 而是 最少几步能跳到最
  • Leetcode 55 跳跃游戏

    题意理解 非负整数数组 nums 最初位于数组的 第一个下标 数组中的每个元素代表你在该位置可以跳跃的最大长度 需要跳到nums最后一个元素即为成功 目标 是否能够跳到最后一个元素 解题思路 使用贪心算法来解题 需要理解局部解和最优解的关系
  • LeetCode 2397. 被列覆盖的最多行数,状态压缩优化回溯法

    一 题目 1 题目描述 给你一个下标从 0 开始 大小为 m x n 的二进制矩阵 matrix 另给你一个整数 numSelect 表示你必须从 matrix 中选择的 不同 列的数量 如果一行中所有的 1 都被你选中的列所覆盖 则认为这
  • 浅谈归并排序:合并 K 个升序链表的归并解法

    在面试中遇到了这道题 如何实现多个升序链表的合并 这是 LeetCode 上的一道原题 题目具体如下 用归并实现合并 K 个升序链表 LeetCode 23 合并K个升序链表 给你一个链表数组 每个链表都已经按升序排列 请你将所有链表合并到
  • 矩阵基本操作3

    题目描述 问题描述 定义一个N M N M lt 100 的矩阵 将一个该矩阵的行和列的元素互换 存到另一个二维数组中 输入格式 一行两个整数 N M 中间用空格隔开 表示矩阵有N行 M列 接下来共N行M列表示矩阵 输出格式 输出转置以后的
  • 最大流-Dinic算法,原理详解,四大优化,详细代码

    文章目录 零 前言 一 概念回顾 可略过 1 1流网络 1 2流 1 3最大流 1 4残留网络 1 5增广路

随机推荐

  • 网关Netfilx Zuul:---(Eureka高可用操作)

    之前我们创建完成了3个Eureka的客户端的服务操作 你会发现我们还是没有能够通过微服来进行对他访问 还是必须通过自己服务的端口号来进行访问 那么我们的微服务是没有能够完成的 这个时候我们就需要通过网关进行操作 其实网关就是为客户端提供统一
  • 使用IntelliJ IDEA中的Spring Initializr来快速构建Spring Boot/Cloud工程

    我相信许多初学者都看了Spring Boot和Spring Cloud相关的博文中 都会涉及Spring Boot工程的创建的问题 而一般所看到的都是使用IntelliJ IDEA 工具来创建 并且方便许多 而创建的方式多种多样之前我是通过
  • 标签下载文件重命名失败,download 无效

    最近用到 a 标签实现文件下载并对文件进行重新命名 遇到了一些问题 文件重命名一直失败 所幸最终还是解决了 在此记录一下 避免后来者踩坑 HTML a 元素可以创建一个到其他网页 文件 同一页面内的位置 电子邮件地址或任何其他URL的超链接
  • 极验滑块识别-通用滑块识别

    遇到滑块问题 在写爬虫的时候 经常会遇到滑块问题 很多次都想过尝试如何攻破滑块 但是每次都没成功 除了最开始的极验滑块 当时通过原图和滑块图的对比 能够得出缺口坐标 但是随着极验 网易 腾讯滑块的更新 已经不能够找到原图了 下面给出滑块通杀
  • MATLAB中表示点形状、颜色的常见符号

    颜色字符串有 c m y r g b w 和k 分别表示青 红紫 黄 红 绿 白和黑 线型字符串有 为实线 为虚线 为点线 为点虚线 及 none 表示不用线型 标记形式有 o 和 x 填入 s 代表正方形 d 代表菱形 A 为上三角形 v
  • 2020第十一届蓝桥杯10月份省赛真题(JavaB组题解)

    2020第十一届蓝桥杯10月份省赛真题 JavaB组题解 试题 A 门牌制作 试题 B 寻找 2020 试题 C 蛇形填数 试题 D 七段码 试题 E 排序 试题 F 成绩分析 试题 G 单词分析 试题 H 数字三角形 试题 I 子串分值和
  • 代码质量的评价标准

    如何评价代码质量 代码质量的评价比较主观 一般会使用以下几个词汇 可读性 可扩展性 可维护性 灵活 优雅 可重用性 可测试性 这些是从不同方面来评价 但是各个维度都彼此关联 譬如可读性和可扩展性好 我们就说这段代码的可维护性比较好 代码质量
  • QT多线程下的信号与槽机制

    目录 1 QThread类 2 创建并启动线程 3 多线程信号与槽 4 信号与槽的调用线程 5 调整信号与槽所在线程的依附关系 6 信号与槽的连接方式 QT 中 QObject 作QT中类的最终父类 具有自定义信号与槽的能力 只要继承自这个
  • javaj经典程序编程50题

    JAVA基础编程练习50题 本文对50道经典的java程序题进行详细解说 对于初学者可以跳过一些逻辑性太强的题目 比如第一题用到了方法的递归 初学者可能不理解 最好先看那些有if for while可以简单解决的程序题 但是 对于比较深入学
  • 4键电子手表说明书_4键电子手表怎么调时间的方法

    现在除了很多喜欢购买机械表以外 还有很多人喜欢购买石英表 其中就有很多人购买了4键电子手表 但是很多人往往却并不知道4键电子手表怎么调时间 那么我们今天拿卡西欧4键电子手表为例子 给大家讲解以下4键电子手表怎么调时间 首先 我们可以轻松观察
  • Linux删除文件夹命令

    Linux删除文件夹命令 linux删除目录很简单 很多人还是习惯用rmdir 不过一旦目录非空 就陷入深深的苦恼之中 现在使用rm rf命令即可 直接rm就可以了 不过要加两个参数 rf 即 rm rf 目录名字 r 就是向下递归 不管有
  • milvus笔记01--部署测试版本 milvus

    milvus笔记01 部署测试版本milvus 1 milvus 简介 2 milvus cpu 部署 2 1 基于sqlite部署milvus 2 2 基于mysql部署milvus 3 常见命令 3 1 api 案例 3 2 RESTf
  • 使用 Github Action 将 github 仓库同步到 gitee

    背景 最近将 CI CD 流程改造了一波 使用 ArgoCD 做 gitops 这样所有的集群 Yaml 文件就都存放在了 github 上的一次仓库里 但是小服务器放在家里 从 github 上拉代码时总是时不时有网络问题 导致集群资源无
  • -1. HTML&CSS 基础总结

    HTML CSS Favorite 1 基础知识 1 HTML 1 1基本结构标签 1 骨架 2 排版标签 标题标签 h1 标题文本 h1 h1 gt h1 h6 段落标签 p 段落文本内容 p 水平线标签 hr 水平线 换行标签 br 换
  • Android 解析软件包时出现问题 -- Error staging apk from content URI

    Android Version 8 1 使用场景 在Rk3288w Android 8 1 的测试设备上安装 文件管理器 应用程序 若打开 apk文件 会出现 解析包错误 提示 即安装失败 影响使用 如下为ActivityManagerSe
  • 华为OD机试真题-找出重复代码【2023.Q1】

    题目描述 小明负责维护项目下的代码 需要查找出重复代码 用以支撑后续的代码优化 请你帮助小明找出重复的代码 重复代码查找方法 以字符串形式给出两行代码 字符审长度1 lt length lt 100 由英文字母 数字和空格组成 找出两行代码
  • 扩展磁盘大小

    各个系统可能会有些差异 主要存在于文件系统和卷组名上 一定要注意 如果要进行扩展大小的话 一定要先把原来的那个卷的数据进行保存好 数据 bin bash 使用这个脚本时 只需将第一个参数设置为想扩展多大即可 但是需要注意的是 若移植到位置的
  • java char长度_Java中char的字节数

    以前一直以为char占一个字节 后来发现远没这么简单 Java中char的字节数 和编码有关 使用UTF 8 英文字符占1个字节 中文占3个字节 下面在是在Ubuntu中测试的结果 public static void main Strin
  • 方差

    方差在概率统计中有很重要的作用 2公式 方差 方差是实际值与 期望值之差 平方的期望值 而 标准差是方差算术 平方根 1 在实际计算中 我们用以下公式计算方差 方差是各个数据与 平均数之差的平方的和的平均数 即 其中 x 表示 样本的平均数
  • 前缀树

    前缀树的结构 Trie树 又叫字典树 前缀树 Prefix Tree 单词查找树或键树 是一种多叉树结构 如下图 上图是一棵Trie树 表示了关键字集合 a to tea ted ten i in inn Trie树的基本性质 根节点不包含