数据结构与算法:字典树(前缀树)

news/2024/11/30 13:45:11/

数据结构与算法:字典树

本节目标:了解c语言和Python如何写前缀树

本节内容:前缀树

本节阅读需要(20)min。
本节实操需要(20)min。


文章目录

  • 数据结构与算法:字典树
  • 前言
  • 一、C版本的前缀树
    • 节点的创建。
    • 查询
  • 二、Python版本的前缀树
  • 总结


前言

1. 技能的意义所在。
2. 内容中概念的提出

前缀树的本质其实是多分支多层次的字典。


一、C版本的前缀树

节点的创建。

public class TrieNode {int count;int prefix;TrieNode[] nextNode=new TrieNode[26];public TrieNode(){count=0;prefix=0;}
}

TrieNode[] nextNode=new TrieNode[26]为什么是26,很简单,因为26个英文字母。也就是说只有有限的26种后缀。
并且通过数列的位置去编号字母的。

查询

//插入一个新单词public static void insert(TrieNode root,String str){if(root==null||str.length()==0){return;}char[] c=str.toCharArray();for(int i=0;i<str.length();i++){//如果该分支不存在,创建一个新节点if(root.nextNode[c[i]-'a']==null){root.nextNode[c[i]-'a']=new TrieNode();}root=root.nextNode[c[i]-'a'];root.prefix++;//注意,应该加在后面}//以该节点结尾的单词数+1root.count++;}
//查找该单词是否存在,如果存在返回数量,不存在返回-1public static int search(TrieNode root,String str){if(root==null||str.length()==0){return -1;}char[] c=str.toCharArray();for(int i=0;i<str.length();i++){//如果该分支不存在,表名该单词不存在if(root.nextNode[c[i]-'a']==null){return -1;}//如果存在,则继续向下遍历root=root.nextNode[c[i]-'a'];	}//如果count==0,也说明该单词不存在if(root.count==0){return -1;}return root.count;}//查询以str为前缀的单词数量public static int searchPrefix(TrieNode root,String str){if(root==null||str.length()==0){return -1;}char[] c=str.toCharArray();for(int i=0;i<str.length();i++){//如果该分支不存在,表名该单词不存在if(root.nextNode[c[i]-'a']==null){return -1;}//如果存在,则继续向下遍历root=root.nextNode[c[i]-'a'];	}return root.prefix;}

注意这里有两个数量。
一个是到这个节点为止的前缀字符串的数量。
一个是以这个节点为止的前缀的完整单词的数量。

二、Python版本的前缀树

class TreeNode(object):def __init__(self):self.nodes = {}         # 记录当前结点的子结点self.is_leaf = False   # 当前结点是否表示一个单词self.count = 0          # 单词树中单词的总量def insert(self,word):curr = selffor c in word:if not curr.nodes.get(c,None):new_node = TreeNode()curr.nodes[c] = new_nodecurr = curr.nodes[c]curr.is_leaf = Trueself.count += 1returndef insert_many(self,words):for word in words:self.insert(word)returndef search(self,word):curr = selftry:for c in word:curr = curr.nodes[c]except:return Falsereturn curr.is_leaf

总结

前缀树适用的场景。
1、低存储地维护字符串集合(即字典)。

2、向字符串集合中插入字符串(即建树)。

3、查询字符串集合中是否有某个字符串(即查询)。

4、统计字符串在集合中出现的个数(即统计)。

5、将字符串集合按字典序排序(即字典序排序)。

6、求集合内两个字符串的LCP(Longest Common Prefix,最长公共前缀)(即求最长公共前缀)

必须满足的条件:
1.后缀可能性是有限的。不然就是图了。
2.这些节点不重复,因为键名是不能重复的。

附目前发现的所有官标Hard实际难度为Easy的题目:154,273,745,829,987,1095,1220,1601,2151,2296(最后一个视语言而定)


http://www.ppmy.cn/news/39091.html

相关文章

使用BeanDefinitionRegistryPostProcessor扫描指定包下Bean对象时,@Configuration无法创建内部中@Bean的类

文章目录1. 前言2. 先说结论3. 代码验证1. 前言 在之前工作中需要设计SDK(第三方jar包)&#xff0c;该SDK中是有bean对象的&#xff0c;从而需要考虑该包下的会成为Bean的类要如何被spring扫描到从而创建&#xff0c;因此写了如下文章&#xff1a; 设计第三方jar包中有bean对象…

计算虚拟化之内存管理

CPU 的虚拟化是用户态的 qemu 和内核态的 KVM 共同配合完成的。它们二者通过 ioctl 进行通信。对于内存管理来讲&#xff0c;也是需要这两者配合完成的。 操作系统给每个进程分配的内存都是虚拟内存&#xff0c;需要通过页表映射&#xff0c;变成物理内存进行访问。当有了虚拟…

netty 实现websocket 携带参数建立连接

Netty提供了很好的WebSocket支持&#xff0c;可以通过添加WebSocketServerProtocolHandler实现暴露一个WebSocket接口。但是&#xff0c;如果需要在WebSocket的URI中添加参数queryString&#xff0c;例如/im/ws?w221100234&t99&#xff0c;则连接可能无法建立&#xff0c;…

MySQL学习笔记(十五)——索引的创建和设计原则

1. 为什么使用索引 1.1 不加索引 没有索引&#xff0c;整张表读取数据&#xff0c;然后利用数据来比较条件&#xff0c;捞出符合条件的数据&#xff0c;表有很多数据&#xff0c;这些数据都会通过磁盘IO来读取&#xff0c;很耗时。 1.2 加索引 加索引后 &#xff0c;通过索引…

Mybatis高阶使用

1.Mybatis拦截器 Mybatis——拦截器Interceptor_mybatis interceptor_七海健人的博客-CSDN博客 mybatis拦截器使用及原理_metaobject.forobject_huang_ma的博客-CSDN博客 手把手教你开发 MyBatis 插件 - 知乎 2.Mybatis工具类 MetaObject MetaClass https://www.cnblogs.co…

leetcode 面试题 17.06. 2出现的次数

编写一个方法&#xff0c;计算从 0 到 n (含 n) 中数字 2 出现的次数。 示例: 输入: 25 输出: 9 解释: (2, 12, 20, 21, 22, 23, 24, 25)(注意 22 应该算作两次) 该问题用的方法数数组dp&#xff0c;首先我通过总结规律写出了相关的code。使用一个dp数组记录10i10^i10i以内会出…

加多宝二次创业五周年:解锁品牌持续增长密码

今年作为后疫情时代元年&#xff0c;首要的任务是提振经济、重振信心&#xff0c;其中消费市场的提振至关重要。 春江水暖鸭先知。每当消费市场开始复苏&#xff0c;食品饮料行业的回暖一般会更明显。而要扩大食品饮料的消费规模、提振消费信心&#xff0c;关键在于品牌结合外…

NVIDIA jetson tensorrt加速yolov5摄像头检测

link 在使用摄像头直接检测目标时&#xff0c;检测的实时画面还是有点慢&#xff0c;下面是tensorrt加速过程记录。 一、设备 1、设备jetson agx xavier 2、jetpack4.6.1 3、tensorrt 8.2.1.8 4、conda虚拟环境 python3.6 二、虚拟环境搭建及依赖 1、参考此博客安装torch Nvidi…