[转] 浅谈Trie树(字典树)
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html
Trie树(字典树)
一、引入
字典是干啥的?查找字的。
字典树自然也是起查找作用的。查找的是啥?单词。
看以下几个题:
1、给出n个单词和m个询问,每次询问一个单词,回答这个单词是否在单词表中出现过。
答:简单!map,短小精悍。
好。下一个
2、给出n个单词和m个询问,每次询问一个前缀,回答询问是多少个单词的前缀。
答:map,把每个单词拆开。
judge:n<=200000,TLE!
这就需要一种高级数据结构——Trie树(字典树)
二、原理
在本篇文章中,假设所有单词都只由小写字母构成
对cat,cash,app,apple,aply,ok 建一颗字典树,建成之后如下图所示

由此可以看出:
1、字典树用边表示字母
2、有相同前缀的单词公用前缀节点,那我们可以的得出每个节点最多有26个子节点(在单词只包含小写字母的情况下)
3、整棵树的根节点是空的。为什么呢?便于插入和查找,这将会在后面解释。
4、每个单词结束的时候用一个特殊字符表示,图中用的‘′,那么从根节点到任意一个‘′,那么从根节点到任意一个‘’所经过的边的所有字母表示一个单词。
三、基本操作
A、insert,插入一个单词
1.思路
从图中可以直观看出,从左到右扫这个单词,如果字母在相应根节点下没有出现过,就插入这个字母;否则沿着字典树往下走,看单词的下一个字母。
这就产生一个问题:往哪儿插?计算机不会自己选择位置插,我们需要给它指定一个位置,那就需要给每个字母编号。
我们设数组trie[i][j]=k,表示编号为i的节点的第j个孩子是编号为k的节点。
什么意思呢?
这里有2种编号,一种是i,k表示节点的位置编号,这是相对整棵树而言的;另一种是j,表示节点i的第j的孩子,这是相对节点i而言的。
不理解?看图
还是单词cat,cash,app,apple,aply,ok
我们就按输入顺序对其编第一种号,红色表示编号结果。因为先输入的cat,所以c,a,t分别是1,2,3,然后输入的是cash,因为c,a是公共前缀,所以从s开始编,s是4,以此类推。
注意这里相同字母的编号可能不同

第二种编号,相对节点的编号,紫色表示编号结果。
因为每个节点最多有26个子节点,我们可以按他们的字典序从0——25编号,也就是他们的ASCLL码-a的ASCLL码。
注意这里相同字母的编号相同

实际上每个节点的子节点都应该从0编到——25,但这样会发现许多事根本用不到的。比如上图的根节点应该分出26个叉。节约空间,用到哪个分哪个。
这样编号有什么用呢?
回到数组trie[i][j]=k。 数组trie[i][j]=k,表示编号为i的节点的第j个孩子是编号为k的节点。
那么第二种编号即为j,第一种编号即为i,k
2、代码

void insert()//插入单词s
{
len=strlen(s);//单词s的长度
root=0;//根节点编号为0
for(int i=0;i<len;i++)
{
int id=s[i]-'a';//第二种编号
if(!trie[root][id])//如果之前没有从root到id的前缀
trie[root][id]=++tot;//插入,tot即为第一种编号
root=trie[root][id];//顺着字典树往下走
}
}

B、search,查找
查找有很多种,可以查找某一个前缀,也可以查找整个单词。
再次我们以查找一个前缀是否出现过为例讲解
1、思路
从左往右以此扫描每个字母,顺着字典树往下找,能找到这个字母,往下走,否则结束查找,即没有这个前缀;前缀扫完了,表示有这个前缀。
2、代码

bool find()
{
len=strlen(s);
root=0;//从根结点开始找
for(int i=0;s[i];i++)
{
int x=s[i]-'a';//
if(trie[root][x]==0) return false;//以root为头结点的x字母不存在,返回0
root=trie[root][x];//为查询下个字母做准备,往下走
}
return true;//找到了
}

3、如果是查询某个单词的话,我们用bool变量 v[i]表示节点i是否是单词结束的标志。
那么最后return的是v[root],所以在插入操作中插入完每个单词是,要对单词最后一个字母的v[i]置为true,其他的都是false
4、如果是查询前缀出现的次数的话,那就在开一个sum[],表示位置i被访问过的次数,
那么最后return的是sum[root],插入操作中每访问一个节点,都要让他的sum++
这里前缀的次数是标记在前缀的最后一个字母所在位置的后一个位置上。
比如:前缀abc出现的次数标记在c所在位置的后一个位置上,

五、模板题
hud 1251 统计难题 http://acm.hdu.edu.cn/showproblem.php?pid=1251
codevs 4189 字典 http://codevs.cn/problem/4189/
[转] 浅谈Trie树(字典树)的更多相关文章
- (转)浅谈trie树
浅谈Trie树(字典树) Trie树(字典树) 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看以下几个题: 1.给出n个单词和m个询问,每次询问 ...
- 剑指Offer——Trie树(字典树)
剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种的单词.对于每一个单词,我们要判断他出没出现过,如果出现了,求第一次出现在第几个位 ...
- AC自动机——1 Trie树(字典树)介绍
AC自动机——1 Trie树(字典树)介绍 2013年10月15日 23:56:45 阅读数:2375 之前,我们介绍了Kmp算法,其实,他就是一种单模式匹配.当要检查一篇文章中是否有某些敏感词,这其 ...
- Trie(字典树)
没时间整理了,老吕又讲课了@ @ 概念 Trie即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种,典型应用是统计和排序大量的字符串(不限于字符串) Trie字典树主要用于存储字符串, ...
- 9-11-Trie树/字典树/前缀树-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版
课本源码部分 第9章 查找 - Trie树/字典树/前缀树(键树) ——<数据结构>-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ <数据结构-C语言版>(严蔚 ...
- 浅谈Trie
所谓\(Trie\)就是字典树. 何为字典树?想象一下我们平时用拼音查字法在字典树查汉字的时候,一位一位确定这个汉字的拼音从而翻到我们想要看的那一面. 所以\(Trie\)树跟字典一样,是一种逐位检索 ...
- 浅谈Trie树(字典树)
Trie树(字典树) 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看以下几个题: 1.给出n个单词和m个询问,每次询问一个单词,回答这个单词是否在单 ...
- 浅谈 trie树 及其实现
定义:又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构, 如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. 核心思想:是空间换时间.利用字符串的公共前缀来降低查询时间的开 ...
- 浅谈Trie树
Trie树,也叫字典树.顾名思义,它就是一个字典 字典是干什么的?查找单词!(英文字典哦) 个人认为字典树这个名字起得特别好,因为它真的跟字典特别像,一会r你就知道了. 注:trie的中文翻译就是单词 ...
随机推荐
- 【简单易用的傻瓜式图标设计工具】Logoist 3.1 for Mac
[简介] Logoist 是一款Mac上强大易用的傻瓜式图标设计制作工具,通过使用内置模板和预设效果,您可以立即创建高质量的图形内容和艺术作品.通过使用该应用程序,可用于制作图标LOGO. 一款用于创 ...
- 冒泡排序Java版
package dataStructureAlgorithmReview.day01; import java.util.Arrays; /** * 冒泡 * @author shundong * * ...
- bzoj4034 线段树+dfs序
https://www.lydsy.com/JudgeOnline/problem.php?id=4034 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 ...
- SSM结构
代码结构为 src:controller / mapper / entity / service /(serviceiml) webcontent:META-INF WEB-INF:lib(包含所 ...
- Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术
catalogue 1. 引言2. 使用注册表注入DLL3. 使用Windows挂钩来注入DLL4. 使用远程线程来注入DLL5. 使用木马DLL来注入DLL6. 把DLL作为调试器来注入7. 使用c ...
- nginx 前端POST请求405问题解决与排查过程
问题描述 在请求时,f12提示POST请求报错405 环境描述 nginx转发至后端nginx,后端nginx转发至后端golang api接口 解决步骤 根据网上方法排查,发现80%以上无非就是以下 ...
- 有关mysql的innodb_flush_log_at_trx_commit参数
一.参数解释 0:log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下在事务提交的时候,不会主动触发写入磁盘的操作. 1:每次事务 ...
- HDU 1030(三角数阵 数学)
题意是问在给定的三角形数阵中从一个数到另一个数所要跨过的边数. 最初的时候很迷,除了发现每层的数字个数与层数间的关系和每层数最后一个数与层数的关系外什么也没看出来,打算先求出数字所在的层数,然后计算到 ...
- vue中slot插槽
插槽就是vue实现的一套内容分发的API,将插槽元素作为承载分发内容的出口. 也就是说在组件模板中默认占用一个位置,当使用组件标签时候,组件标签的内容就会自动替换掉内容 slot中可以设置一些默认的内 ...
- Linux常用bash命令
目录 bash命令 基础操作 export | whereis | which | clear 文件操作 ls | touch | cat | more | head | tail | mv | cp ...