Trie树总结
Trie,又经常叫前缀树,字典树等等。它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree。当然很多名字的意义其实有交叉。
定义
在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。
trie中的键通常是字符串,但也可以是其它的结构。trie的算法可以很容易地修改为处理其它结构的有序序列,比如一串数字或者形状的排列。比如,bitwise trie中的键是一串位元,可以用于表示整数或者内存地址
基本性质
1.根节点不包含字符,除根节点意外每个节点只包含一个字符。
2.从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
3.每个节点的所有子节点包含的字符串不相同。
优点:
可以最大限度地减少无谓的字符串比较,故可以用于词频统计和大量字符串排序。
缺点: 虽然不同单词共享前缀,但其实trie是一个以空间换时间的算法。其每一个字符都可能包含至多字符集大小数目的指针(不包含卫星数据)。
应用场景:
(1) 字符串检索 事先将已知的一些字符串(字典)的有关信息保存到trie树里,查找另外一些未知字符串是否出现过或者出现频率。
1000万字符串,其中有些是重复的,需要把重复的全部去掉,保留没有重复的字符串。
(2)文本预测、自动完成,see also,拼写检查
(3)词频统计
若无内存限制:Trie + “k-大/小根堆”(k为要找到的数目)。
否则,先hash分段再对每一个段用hash(另一个hash函数)统计词频,再要么利用归并排序的某些特性(如partial_sort),要么利用某使用外存的方法。
(4)排序
Trie树是一棵多叉树,只要先序遍历整棵树,输出相应的字符串便是按字典序排序的结果。 比如给你N 个互不相同的仅由一个单词构成的英文名,让你将它们按字典序从小到大排序输出。
(5)字符串最长公共前缀
Trie树利用多个字符串的公共前缀来节省存储空间,当我们把大量字符串存储到一棵trie树上时,我们可以快速得到某些字符串的公共前缀。
eg: 给出N 个小写英文字母串,以及Q 个询问,即询问某两个串的最长公共前缀的长度是多少?
解决方案:首先对所有的串建立其对应的字母树。此时发现,对于两个串的最长公共前缀的长度即它们所在结点的公共祖先个数,于是,问题就转化为了离线(Offline)的最近公共祖先(Least Common Ancestor,简称LCA)问题。 而最近公共祖先问题同样是一个经典问题,可以用下面几种方法:
- 利用并查集(Disjoint Set),可以采用采用经典的Tarjan 算法;
- 求出字母树的欧拉序列(Euler Sequence )后,就可以转为经典的最小值查询(Range Minimum Query,简称RMQ)问题了;
(6)字符串搜索的前缀匹配
trie树常用于搜索提示。如当输入一个网址,可以自动搜索出可能的选择。当没有完全匹配的搜索结果,可以返回前缀最相似的可能。 Trie树检索的时间复杂度可以做到n,n是要检索单词的长度, 如果使用暴力检索,需要指数级O(n^2)的时间复杂度。
(7) 作为其他数据结构和算法的辅助结构
如后缀树,AC自动机等(后缀树可以用于全文搜索
模板
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1e6 + 5;
int cnt = 1, Trie[MAXN][26];
int End[MAXN];
void Insert(char s[], int len) {
int p = 1;
for(int i = 0; i < len; i++) {
int ch = s[i] - 'a';
if(Trie[p][ch] == 0)
Trie[p][ch] = ++cnt;
p = Trie[p][ch];
}
End[p]++;
}
int search(char s[], int len) {
int p = 1;
for(int i = 0; i < len; i++) {
int ch = s[i] - 'a';
p = Trie[p][ch];
if(!p)
return false;
}
return End[p];
}
char st[MAXN], ask[MAXN];
int main() {
int n, m;
scanf ("%d %d", &n, &m);
for(int i = 1; i <= n; i++) {
scanf ("%s", st);
Insert(st, strlen(st));
}
for(int i = 1; i <= m; i++) {
scanf ("%s", st);
int len = 0, ans = 0;
for(int j = 1; j <= strlen(st); j++)
ans += search(st, j);
printf("%d\n", ans);
}
return 0;
}
Trie树总结的更多相关文章
- 基于trie树做一个ac自动机
基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...
- 基于trie树的具有联想功能的文本编辑器
之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...
- hihocoder-1014 Trie树
hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...
- 洛谷P2412 查单词 [trie树 RMQ]
题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...
- 通过trie树实现单词自动补全
/** * 实现单词补全功能 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #incl ...
- #1014 Trie树
本题主要是求构造一棵Trie树,即词典树用于统计单词. C#代码如下: using System; using System.Collections.Generic; using System.Lin ...
- Trie树-字典查找
描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题: ...
- Trie树的创建、插入、查询的实现
原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28977986&id=3807947 1.什么是Trie树 Tr ...
- Trie树(c++实现)
转:http://www.cnblogs.com/kaituorensheng/p/3602155.html http://blog.csdn.net/insistgogo/article/detai ...
- [转]双数组TRIE树原理
原文名称: An Efficient Digital Search Algorithm by Using a Double-Array Structure 作者: JUN-ICHI AOE 译文: 使 ...
随机推荐
- js根据ip地址获取城市地理位置
一.使用js根据ip获取地址位置 <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>& ...
- STM32入门系列-CMSIS标准
使用寄存器点亮开发板上LED,这种开发方式显然是不适合大众,对于STM32这样庞大的芯片,内部寄存器实在太多,如果操作的外设比较多,那么就需要花很多时间查询底层寄存器内容,而且即使程序写好,如果要换其 ...
- python开发基础(二)运算符以及数据类型之float(浮点类型)
# encoding: utf-8 # module builtins # from (built-in) # by generator 1.147 """ Built- ...
- rabbitmq集群搭建,镜像队列搭建
原文地址:https://www.jianshu.com/p/11963564dd3d 教你如何从0开始搭建rabbitmq集群 一.准备工作 1.三台centos虚拟机 2.三台虚拟机都安装了doc ...
- 【SpringBoot】03.SpringBoot整合Servlet的两种方式
SpringBoot整合Servlet的两种方式: 1. 通过注解扫描完成Servlet组件注册 新建Servlet类继承HttpServlet 重写超类doGet方法 在该类使用注解@WebServ ...
- NoSQL数据库的四大分类的分析
分类 Examples举例 典型应用场景 数据模型 优点 缺点 键值(key-value) Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB 内容缓 ...
- C语言利用结构体数组实现学生成绩管理系统
这篇文章主要为大家详细介绍了C语言利用结构体数组实现学生成绩管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 要求: 某班有最多不超过30人(具体人数由键盘输入) ...
- 12装饰器及*args,**kwargs
注:参数和返回值都是一个函数. 1,无参数 def decotare1(func): def wrapper(): print("First") func() return wra ...
- 洛谷日报 & 原来博客(转载)
震惊,新的功能:可以按Ctrl + F 进行关键字查询. \(update\) on 10.26:把这两个月的日报也加入进去了,并且修复了几个错误. 本文会把小编用过的博客和比较好的博客放在这里. 可 ...
- 《.NET 5.0 背锅案》第2集:码中的小窟窿,背后的大坑,发现重要嫌犯 EnyimMemcachedCore
在第1集的剧情中,主角是".NET 5.0 正式版 docker 镜像",它有幸入选第1位嫌疑对象,不是因为它的嫌疑最大,而是它的验证方法最简单,只需要再进行一次发布即可.我们在周 ...