内存空间有限情况下的词频统计 Trie树 前缀树
数据结构与算法专题——第十二题 Trie树
https://mp.weixin.qq.com/s/nndr2AcECuUatXrxd3MgCg
今天来聊一聊Trie树,Trie树的名字有很多,比如字典树,前缀树等等。
一:概念
下面有and,as,at,cn,com这几个关键词,构建成 trie 树如下。

从上面图中,应该可以或多或少的发现一些好玩的特性。
- 根节点不包含字符,除根节点外的每一个子节点都包含一个字符。
- 从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串。
- 每个单词的公共前缀作为一个字符节点保存。
二:使用范围
既然学Trie树,肯定要知道这玩意是用来干嘛的?
1. 词频统计。
可能有人要说了,词频统计简单啊,一个hash或者一个堆就可以打完收工,但问题来了,如果内存有限呢?还能这么玩吗?这种限制级条件下就可以用trie树来压缩下空间,因为公共前缀都是用一个节点保存的。
2. 前缀匹配
就拿上面的图来说吧,如果我想获取所有以 "a" 开头的字符串,从图中可以很明显的看到是:and,as,at,如果不用trie树,你该怎么做呢?很显然朴素的做法时间复杂度为O(N2) ,用Trie树就不一样了,它可以做到h,h为你检索单词的长度,可以说这是秒杀的效果。
举个例子:现有一个编号为1的字符串”and“,怎样插入到trie树中呢?采用动态规划的思想,将编号”1“计入到每个途径的节点中,那么以后我们要找”a“,”an“,”and"为前缀的字符串的编号将会轻而易举。

三:实际操作
到现在为止,我想大家已经对trie树有了大概的掌握,下面看看如何来实现。
1:定义trie树节点
为了方便,我也采用纯英文字母,大家都知道字母有26个,所以构建的trie树就是一个26叉树,每个节点包含26个子节点,实现代码如下:
/// <summary>
/// Trie树节点
/// </summary>
public class TrieNode
{
/// <summary>
/// 26个字符,也就是26叉树
/// </summary>
public TrieNode[] childNodes;
/// <summary>
/// 词频统计
/// </summary>
public int freq;
/// <summary>
/// 记录该节点的字符
/// </summary>
public char nodeChar;
/// <summary>
/// 插入记录时的编码id
/// </summary>
public HashSet<int> hashSet = new HashSet<int>();
/// <summary>
/// 初始化
/// </summary>
public TrieNode()
{
childNodes = new TrieNode[26];
freq = 0;
}
}
2: 添加操作
从上面图中,应该可以或多或少的发现一些好玩的特性。
- 根节点不包含字符,除根节点外的每一个子节点都包含一个字符。
- 从根节点到某一节点,路径上经过的字符连接起来,就是该节点对应的字符串。
- 每个单词的公共前缀作为一个字符节点保存。
二:使用范围
既然学Trie树,肯定要知道这玩意是用来干嘛的?
1. 词频统计。
可能有人要说了,词频统计简单啊,一个hash或者一个堆就可以打完收工,但问题来了,如果内存有限呢?还能这么玩吗?这种限制级条件下就可以用trie树来压缩下空间,因为公共前缀都是用一个节点保存的。
2. 前缀匹配
就拿上面的图来说吧,如果我想获取所有以 "a" 开头的字符串,从图中可以很明显的看到是:and,as,at,如果不用trie树,你该怎么做呢?很显然朴素的做法时间复杂度为O(N2) ,用Trie树就不一样了,它可以做到h,h为你检索单词的长度,可以说这是秒杀的效果。
举个例子:现有一个编号为1的字符串”and“,怎样插入到trie树中呢?采用动态规划的思想,将编号”1“计入到每个途径的节点中,那么以后我们要找”a“,”an“,”and"为前缀的字符串的编号将会轻而易举。
内存空间有限情况下的词频统计 Trie树 前缀树的更多相关文章
- 软工之词频统计器及基于sketch在大数据下的词频统计设计
目录 摘要 算法关键 红黑树 稳定排序 代码框架 .h文件: .cpp文件 频率统计器的实现 接口设计与实现 接口设计 核心功能词频统计器流程 效果 单元测试 性能分析 性能分析图 问题发现 解决方案 ...
- LeetCode 80,不使用外部空间的情况下对有序数组去重
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题的第49篇文章,我们一起来看LeetCode的第80题,有序数组去重II(Remove Duplicates fr ...
- Linux查看磁盘目录内存空间使用情况
du 显示每个文件和目录的磁盘使用空间 命令参数 -c或--total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和. -s或--summarize 仅显示总计,只列出最后加总的 ...
- JS如何在不给新空间的情况下给数组去重?
1.先排序,在让相邻元素对比去重 const nums = [3, 1, 1, 5, 2, 3, 4, 3, 5, 5, 6, 4, 6, 6, 6]; Array.prototype.arrayNo ...
- alloc_page分配内存空间--Linux内存管理(十七)
1 前景回顾 在内核初始化完成之后, 内存管理的责任就由伙伴系统来承担. 伙伴系统基于一种相对简单然而令人吃惊的强大算法. Linux内核使用二进制伙伴算法来管理和分配物理内存页面, 该算法由Know ...
- STM32内存受限情况下摄像头驱动方式与图像裁剪的选择
1.STM32图像接收接口 使用stm32芯片,128kB RAM,512kB Rom,资源有限,接摄像头采集图像,这种情况下,内存利用制约程序设计. STM32使用DCMI接口读取摄像头,协议如下. ...
- 萌新笔记——linux下查看内存的使用情况
windows上有各种软件可以进行"一键加速"之类的操作,释放掉一些内存(虽然我暂时不知道是怎么办到的,有待后续学习).而任务管理器也可以很方便地查看各进程使用的内存情况,如下图: ...
- linux下查看内存的使用情况
windows上有各种软件可以进行“一键加速”之类的操作,释放掉一些内存(虽然我暂时不知道是怎么办到的,有待后续学习).而任务管理器也可以很方便地查看各进程使用的内存情况,如下图: 同样地,linux ...
- 简单统计SQLSERVER用户数据表大小(包括记录总数和空间占用情况)
在SQLSERVER,简单的组合sp_spaceused和sp_MSforeachtable这两个存储过程,可以方便的统计出用户数据表的大小,包括记录总数和空间占用情况,非常实用,在SqlServer ...
随机推荐
- EF Core 封装方法Expression<Func<TObject, bool>>与Func<TObject, bool>区别
unc<TObject, bool>是委托(delegate) Expression<Func<TObject, bool>>是表达式 Expression编译后就 ...
- Xtrabackup备份与恢复
一.Xtrabackup介绍 MySQL冷备.mysqldump.MySQL热拷贝都无法实现对数据库进行增量备份.在实际生产环境中增量备份是非常实用的,如果数据大于50G或100G,存储空间足够的情况 ...
- Java发送企业微信应用消息
1.发送消息与被动回复消息 (1)流程不同:发送消息是第三方服务器主动通知微信服务器向用户发消息.而被动回复消息是 用户发送消息之后,微信服务器将消息传递给 第三方服务器,第三方服务器接收到消息后,再 ...
- Spring-Boot配置文件web性能(服务器)配置项(常用配置项为红色)
参数 介绍 server.address 服务器应绑定到的网络地址 server.compression.enabled = false 如果启用响应压缩 server.compression.exc ...
- 动态REM
什么是rem? rem是相对于根元素html字体大小来计算的,即( 1rem = html字体大小 ) rem和em区别? rem:(root em,根em)根元素的fort-size的大小计算em: ...
- 线程上下文类加载器(Context ClassLoader)
1.线程上下文类加载器是从jdk1.2开始引入的,类Thread中的getContextClassLoader()与setContextClassLoader(ClassLoader c1),分别用来 ...
- 伯俊BOS2.0关于订金单的处理方案
订金单功能调整设计 一. 功能确认 BPOS关于订金的使用对应的是"预收单",原"预收单"设置有商品明细,根据客户对订金的需求,取消原有"商品 ...
- 技术基础 | 监测Apache Cassandra的简明方式——MCAC
点击这里在GitHub上访问我们,以便深入了解DataStax的开源项目--Apache Cassandra指标收集器(Metric Collector for Apache Cassandra, o ...
- 瞄到BindingGroup用法
文章转载于https://www.cnblogs.com/dangnianxiaoqingxin/p/12653988.html 2.BindingGroup的使用 public class MyCl ...
- 基于nginx实现web服务器的双机热备
1.适用场景 对于部署重要的服务,会使用两台服务器,互相备份,共同执行同一服务.当一台服务器出现故障时,可以由另一台服务器承担服务任务,从而在不需要人工干预的情况下,自动保证系统能持续提供服务.双机热 ...