什么是字典树



上图来自luogu题解

这是一种字典树,不过本文讲的不是这种图,本文要讲一种更通俗易懂的(博主个人观点)

我要讲的是每个节点只存一个字母或数字,通过打标记的方法实现find的

像这样



上图来自百度百科

如何存储字典树

我不想写那些很难搞的指针,虽然用指针会使程序简单明了,可能以后会更新上指针版的吧,咕咕咕

个人认为存储字符串只需要按顺序就可以了,这应该也是字典树的精髓

如要顺序存储下面的字符串:"lyqalioi","orzliuzitong","zbqisredsun","orztzt".......

只需用tree[i][j]来表示以i为根的j号孩子的编号(仔细搞搞这里,比较难懂)

用flag[i]来表示以i号节点为结束的字符串有没有(前面的描述不太准确,就是到i号节点的字符串有没有)

然后就可以迭代根编号root了

  1. void add(char *s)
  2. {
  3. int len=strlen(s),root=0/*root为根节点,初始化0*/,id/*id是编号用char-'a'表示*/;
  4. for(int i=0;i<len;++i)
  5. {
  6. id=s[i]-'a';
  7. if(!tree[root][id]) tree[root][id]=++sum;
  8. root=tree[root][id];//更新根节点,之前在博客里写了
  9. }
  10. flag[root]=true;//更新标记
  11. }

如何查找字符串有没有出现

如果彻底懂了上面这里就不用看了

这里就不解释了和上面一样

  1. bool find(char *s)
  2. {
  3. int len=strlen(s),root=0/*root为根节点,初始化0*/,id/*id是编号用char-'a'表示*/;
  4. for(int i=0;i<len;++i)
  5. {
  6. id=s[i]-'a';
  7. if(!tree[root][id]) return false;
  8. root=tree[root][id];
  9. }
  10. if(flag[root]==true) return true;//看有没有出现以root结束的字符串
  11. else return false;
  12. }

第一个图的那种线段树

代码比较复杂,不过效率比上文的高很多,所以本文也会讲解

应用

大多数字典树的题目都不会直接让你搞一棵树就完通常会带有一些附加条件,会在下面的例题中有涉及

例题

1.统计难题

链接

就是统计了个sum[root]没什么好说的

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cmath>
  5. #include<queue>
  6. #include<stack>
  7. #include<vector>
  8. #include<map>
  9. #include<string>
  10. #include<cstring>
  11. #define int long long int
  12. using namespace std;
  13. inline int read() {
  14. char c = getchar();
  15. int x = 0, f = 1;
  16. while(c < '0' || c > '9') {
  17. if(c == '-') f = -1;
  18. c = getchar();
  19. }
  20. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  21. return x * f;
  22. }
  23. const int MAXN=2e6+5;
  24. int tree[MAXN][30],tot,sum[MAXN];
  25. void add(char *s) {
  26. int root=0,id,len=strlen(s);
  27. for(int i=0; i<len; ++i) {
  28. id=s[i]-'a';
  29. if(!tree[root][id]) tree[root][id]=++tot;
  30. sum[tree[root][id]]++;
  31. root=tree[root][id];
  32. }
  33. }
  34. int find(char *s) {
  35. int root=0,id,len=strlen(s);
  36. for(int i=0; i<len; ++i) {
  37. id=s[i]-'a';
  38. if(!tree[root][id]) return 0;
  39. root=tree[root][id];
  40. }
  41. return sum[root];
  42. }
  43. char s[MAXN];
  44. signed main() {
  45. while(gets(s)) {
  46. if(s[0]=='\0') break;
  47. add(s);
  48. }
  49. while(scanf("%s",s)!=EOF) {
  50. cout<<find(s)<<'\n';
  51. }
  52. return 0;
  53. }

2.P2580 于是他错误的点名开始了

P2580 于是他错误的点名开始了

字典树(Trie)学习笔记的更多相关文章

  1. 字典树trie学习

    字典树trie的思想就是利用节点来记录单词,这样重复的单词可以很快速统计,单词也可以快速的索引.缺点是内存消耗大 http://blog.csdn.net/chenleixing/article/de ...

  2. [POJ] #1002# 487-3279 : 桶排序/字典树(Trie树)/快速排序

    一. 题目 487-3279 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 274040   Accepted: 48891 ...

  3. 『字典树 trie』

    字典树 (trie) 字典树,又名\(trie\)树,是一种用于实现字符串快速检索的树形数据结构.核心思想为利用若干字符串的公共前缀来节约储存空间以及实现快速检索. \(trie\)树可以在\(O(( ...

  4. 字典树(Trie)详解

    详解字典树(Trie) 本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构--字典树.字典树也叫Trie树.前缀树.顾名思义,它是一种针对字符串进行维护的数据结构.并且,它的用途超级广泛.建 ...

  5. Python的dict字典结构操作方法学习笔记

    Python的dict字典结构操作方法学习笔记 这篇文章主要介绍了Python的dict字典结构操作方法学习笔记本,字典的操作是Python入门学习中的基础知识,需要的朋友可以参考下 一.字典的基本方 ...

  6. 字典树(Trie)的学习笔记

    按照一本通往下学,学到吐血了... 例题1 字典树模板题吗. 先讲讲字典树: 给出代码(太简单了...)! #include<cstdio> #include<cstring> ...

  7. Trie字典树的学习及理解

    字典树详解见此 我这里学习时主要是看了李煜东的进阶指南里的讲解,以下是书中介绍的内容. Trie,又称字典树,是一种用于实现字符串快速检索的多叉树结构,Tire的每个节点都拥有若干个字符指针,若在插入 ...

  8. 字典树 trie树 学习

    一字典树 字典树,又称单词查找树,Trie树,是一种树形结构,哈希表的一个变种   二.性质 根节点不包含字符,除根节点以外的每一个节点都只包含一个字符: 从根节点到某一节点,路径上经过的字符串连接起 ...

  9. 字典树trie的学习与练习题

    博客详解: http://www.cnblogs.com/huangxincheng/archive/2012/11/25/2788268.html http://eriol.iteye.com/bl ...

随机推荐

  1. Scala 系列(十一)—— 模式匹配

    一.模式匹配 Scala 支持模式匹配机制,可以代替 swith 语句.执行类型检查.以及支持析构表达式等. 1.1 更好的swith Scala 不支持 swith,可以使用模式匹配 match.. ...

  2. Java 8 ArrayList 详解

    GitHub Page: http://blog.cloudli.top/posts/Java-ArrayList/ ArrayList 继承于 AbstractList ,实现了 List.Rand ...

  3. 给基于对话框的MFC程序添加状态栏并实时显示时间

    转载自丝雪儿 1.首先在string table 里添加两个字串,ID分别为IDS_INDICATOR_MESSAGE and IDS_INDICATOR_TIME 2.在你的 dlg.h 类里面加个 ...

  4. Eureka设计原理

    1. Eureka设计原理 1.1. 前言 目前我越来越关注技术原理层面的东西,开始考虑中间件设计背后,要考虑哪些因素,为什么要这样设计,有什么优化的地方,这次来讨论Eureka 1.2. 设计问题 ...

  5. android 连接wifi案例

    1.xml布局文件: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmln ...

  6. Windows 10 下 GCC / LLVM 的安装和使用

    win10下gcc的安装和makehttps://www.jianshu.com/p/46824c62dfed 方案1:直接官方下载安装minGw或Cygwininstall download: ht ...

  7. 【转】在Keil uv5里面添加STC元器件库,不影响其他元件

    先到网上下载stc.CBD(http://download.csdn.net/detail/mao0514/9699117) 还有STC新系列单片机的头文件,宏晶的网站就有 1.在Keil/C51/I ...

  8. Nodejs入门级

    应用不同模块分析 我们来分解一下这个应用,为了实现一个应用,我们需要实现哪些部分呢? 我们需要提供Web页面,因此需要一个HTTP服务器 对于不同的请求,根据请求的URL,我们的服务器需要给予不同的响 ...

  9. Miniconda安装 虚拟环境创建 与包管理

    安装python 之前安装python包,导致了python里面的包不兼容,用管理工具卸载也下载不掉,重新安装也安装不上,没有办法只能卸掉python重装. 安装Anaconda Anaconda指的 ...

  10. datetime,Timestamp和datetime64之间转换

    引入工具包 import datetime import numpy as np import pandas as pd 总览 from IPython.display import Image fr ...