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自动机等(后缀树可以用于全文搜索


模板

题目

  1. #include <cstdio>
  2. #include <cstring>
  3. using namespace std;
  4. const int MAXN = 1e6 + 5;
  5. int cnt = 1, Trie[MAXN][26];
  6. int End[MAXN];
  7. void Insert(char s[], int len) {
  8. int p = 1;
  9. for(int i = 0; i < len; i++) {
  10. int ch = s[i] - 'a';
  11. if(Trie[p][ch] == 0)
  12. Trie[p][ch] = ++cnt;
  13. p = Trie[p][ch];
  14. }
  15. End[p]++;
  16. }
  17. int search(char s[], int len) {
  18. int p = 1;
  19. for(int i = 0; i < len; i++) {
  20. int ch = s[i] - 'a';
  21. p = Trie[p][ch];
  22. if(!p)
  23. return false;
  24. }
  25. return End[p];
  26. }
  27. char st[MAXN], ask[MAXN];
  28. int main() {
  29. int n, m;
  30. scanf ("%d %d", &n, &m);
  31. for(int i = 1; i <= n; i++) {
  32. scanf ("%s", st);
  33. Insert(st, strlen(st));
  34. }
  35. for(int i = 1; i <= m; i++) {
  36. scanf ("%s", st);
  37. int len = 0, ans = 0;
  38. for(int j = 1; j <= strlen(st); j++)
  39. ans += search(st, j);
  40. printf("%d\n", ans);
  41. }
  42. return 0;
  43. }

Trie树总结的更多相关文章

  1. 基于trie树做一个ac自动机

    基于trie树做一个ac自动机 #!/usr/bin/python # -*- coding: utf-8 -*- class Node: def __init__(self): self.value ...

  2. 基于trie树的具有联想功能的文本编辑器

    之前的软件设计与开发实践课程中,自己构思的大作业题目.做的具有核心功能,但是还欠缺边边角角的小功能和持久化数据结构,先放出来,有机会一点点改.github:https://github.com/chu ...

  3. hihocoder-1014 Trie树

    hihocoder 1014 : Trie树 link: https://hihocoder.com/problemset/problem/1014 题意: 实现Trie树,实现对单词的快速统计. # ...

  4. 洛谷P2412 查单词 [trie树 RMQ]

    题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...

  5. 通过trie树实现单词自动补全

    /** * 实现单词补全功能 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #incl ...

  6. #1014 Trie树

    本题主要是求构造一棵Trie树,即词典树用于统计单词. C#代码如下: using System; using System.Collections.Generic; using System.Lin ...

  7. Trie树-字典查找

    描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一本词典,于是小Hi就向小Ho提出了那个经典的问题: ...

  8. Trie树的创建、插入、查询的实现

    原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28977986&id=3807947 1.什么是Trie树 Tr ...

  9. Trie树(c++实现)

    转:http://www.cnblogs.com/kaituorensheng/p/3602155.html http://blog.csdn.net/insistgogo/article/detai ...

  10. [转]双数组TRIE树原理

    原文名称: An Efficient Digital Search Algorithm by Using a Double-Array Structure 作者: JUN-ICHI AOE 译文: 使 ...

随机推荐

  1. 使用百度云服务器BCC搭建网站,过程记录

    1.买了个最低端的百度云云服务器:1G内存+1核+40系统盘,获得一个静态服务IP地址,之前在阿里那边买个一个域名,在百度云备案一下,通过后就可以正常解析,把域名和IP对应起来了,主要目的是熟悉一下整 ...

  2. 华为云FusionInsight湖仓一体解决方案的前世今生

    摘要:华为云发布新一代智能数据湖华为云FusionInsight时再次提到了湖仓一体理念,那我们就来看看湖仓一体的来世今生. 伴随5G.大数据.AI.IoT的飞速发展,数据呈现大规模.多样性的极速增长 ...

  3. 01.axios封装

    1. 始vue化项目 https://www.cnblogs.com/xiaonq/p/11027880.html   vue init webpack deaxios # 使用脚手架创建项目 dea ...

  4. 【原创】Linux虚拟化KVM-Qemu分析(五)之内存虚拟化

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...

  5. fasd

    基本排序算法 冒泡排序 没什么可说的, 改进方法就是加一个标志位防止有序后重复遍历. 由于需要遍历两次, 所以时间复杂度O(N^2) 传送门 --> 冒泡排序 选择排序 外层从0开始默认oute ...

  6. Angular2 初学小记

    1.与Angular1的异同 几乎完全不同(什么鬼~ 1)保留一些特性 表达式仍旧用{{}}. 2)属性指令变为驼峰式 ng-if ---> ngIf 3)ng-repeat被ngFor代替 4 ...

  7. 测试php

    /** * 测试guzzle * * @return void */ public function index() { $client = new GuzzleHttp\Client(); //12 ...

  8. Grafana+Prometheus+node_exporter监控,Grafana无法显示数据的问题

    环境搭建: 被测linux机器上部署了Grafana,Prometheus,node_exporter,并成功启动了它们. Grafana中已经创建了Prometheus数据源,并测试通过,并且导入了 ...

  9. MVC中Cookie的用法(一)

    1创建Cookie 1.1直接创建 Response.Cookies["Account"].Value = "test1"; Response.Cookies[ ...

  10. 解决js中对象中属性是数组中对应元素,不能使用点数组元素(.数组[i])来获取value值来循环,属性不能是数组元素array[i]的问题

    数据类型 //示例 var tags1avg= ['rg2_crt_001_001_avg', 'rg2_crt_001_002_avg', 'rg2_crt_001_003_avg', 'rg2_c ...