又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

应用

  • 串的快速检索 
    给出N个单词组成的熟词表,以及一篇全用小写英文书写的文章,请你按最早出现的顺序写出所有不在熟词表中的生词。
  • 串的排序 
    给定N个互不相同的仅由一个单词构成的英文名,让你将他们按字典序从小到大输出。用字典树进行排序,采用数组的方式创建字典树,这棵树的每个结点的所有儿子很显然地按照其字母大小排序。对这棵树进行先序遍历即可。
  • 最长公共前缀 
    对所有串建立字典树,对于两个串的最长公共前缀的长度即他们所在的结点的公共祖先个数,于是,问题就转化为当时公共祖先问题。

字典树通常用next指针数组指向子结点,构造整棵树;但是在比赛中为了避免使用指针出错可以使用数组模拟指针的存储方式。

结点的结构体:

  1. struct trie{
  2. int next[maxn];//maxn = 字符种类的个数
  3. int v;//记录该字符出现次数
  4. }t[maxm];//maxm = 结点个数

插入的过程就是建树的过程,如果当前当前前缀的子结点中已经出现此时读到的字符,将前缀移动到该子结点,并将这一前缀出现的次数加一;反之,在当前前缀后建立新的对应这一字符的子结点,并将前缀移动到该子结点,赋出现次数的初始值为1。 
用根结点(trie[0])的v记录整棵树的结点个数,新增结点即++trie[0].v; 
代码:

  1. void insert_trie(char *s)
  2. {
  3. int len = strlen(s);
  4. int now = ;
  5. for(int i=;i<len;i++)
  6. {
  7. int key = s[i] - ''; //key的值由字符串字符类型决定
  8. if(t[now].next[key] != -)
  9. {
  10. now = t[now].next[key];
  11. t[now].v ++;
  12. }
  13. else
  14. {
  15. t[now].next[key] = ++t[].v;
  16. now = t[now].next[key];
  17. t[now].v = ;
  18. memset(t[now].next, -, sizeof(t[now].next));
  19. }
  20. }
  21. }
  1.  

查找即在当前的书中查找公共前缀,代码:

  1. int find_trie(char *s)
  2. {
  3. int len = strlen(s);
  4. int now = ,ret = ;
  5. for(int i=;i<len;i++)
  6. {
  7. int key = s[i] - '';
  8. if(t[now].next[key] != -)
  9. {
  10. now = t[now].next[key];
  11. ret = t[now].v;
  12. }
  13. else
  14. return ;
  15. }
  16. return ret;
  17. }
  1.  

字典树的初始化,将所有trie[0].v个结点的v全都还原为0,next数组初始化为-1。 
代码:

  1. void init()
  2. {
  3. for(int i=;i<=t[].v;i++)
  4. {
  5. if(i) t[i].v = ;
  6. memset(t[i].next, -, sizeof(t[i].next));
  7. }
  8. t[].v = ;
  9. }
  1.  

HDU 1251统计难题/一个裸的模版题/

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <string>
  7. #include <vector>
  8. #include <queue>
  9. #include <stack>
  10. #include <set>
  11. #include <map>
  12. #define INF 0x3f3f3f3f
  13. #define EPS 0.00000001
  14. #define lowbit(x) (x&(-x))
  15. using namespace std;
  16. typedef long long ll;
  17.  
  18. const int maxn = ;
  19. typedef struct Trie Trie;
  20. typedef struct Trie* ptr;
  21. struct Trie
  22. {
  23. ptr next[maxn];
  24. int v; //表示一个字典树到此有多少相同前缀的数目
  25. };
  26. ptr root;
  27.  
  28. void init()
  29. {
  30. if(root == NULL)
  31. {
  32. root = (ptr) malloc (sizeof(Trie));
  33. root -> v = ;
  34. for(int j=;j<maxn;j++)
  35. root -> next[j] = NULL;
  36. }
  37. }
  38.  
  39. void Insert(char *s)
  40. {
  41. int len = strlen(s);
  42. ptr now = root;
  43. for(int i=;i<len;i++)
  44. {
  45. int key = s[i] - 'a';
  46. if(now -> next[key] != NULL)
  47. {
  48. now -> next[key] -> v ++;
  49. now = now -> next[key];
  50. }
  51. else
  52. {
  53. ptr tmp = (ptr) malloc (sizeof(Trie));
  54. tmp -> v = ;
  55. for(int j=;j<maxn;j++)
  56. tmp -> next[j] = NULL;
  57. now -> next[key] = tmp;
  58. now = tmp;
  59. }
  60. }
  61. }
  62.  
  63. int findTrie(char *s)
  64. {
  65. int len = strlen(s), ret = ;
  66. ptr now = root;
  67. for(int i=;i<len;i++)
  68. {
  69. int key = s[i] - 'a';
  70. if(now -> next[key] != NULL)
  71. {
  72. now = now -> next[key];
  73. ret = now -> v;
  74. }
  75. else
  76. {
  77. return ;
  78. }
  79. }
  80. return ret;
  81. }
  82.  
  83. int main()
  84. {
  85. init();
  86. char s[];
  87. int flag = ;
  88. while(gets(s) != NULL)
  89. {
  90. if(strlen(s) == )
  91. {
  92. flag = ;
  93. continue;
  94. }
  95. if(!flag) Insert(s);
  96. else cout << findTrie(s) << endl;
  97. }
  98. }

HDU 1671Phone List/要加初始化/

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <cstring>
  5. #include <algorithm>
  6. #include <string>
  7. #include <vector>
  8. #include <queue>
  9. #include <stack>
  10. #include <set>
  11. #include <map>
  12. #define INF 0x3f3f3f3f
  13. #define EPS 0.00000001
  14. #define lowbit(x) (x&(-x))
  15. using namespace std;
  16. typedef long long ll;
  17.  
  18. const int maxn = ;
  19. const int maxm = ;
  20. struct trie{
  21. int next[maxn];
  22. int v;
  23. }t[maxm];
  24. char s[maxm][];
  25.  
  26. void init()
  27. {
  28. for(int i=;i<=t[].v;i++)
  29. {
  30. if(i) t[i].v = ;
  31. memset(t[i].next, -, sizeof(t[i].next));
  32. }
  33. t[].v = ;
  34. }
  35.  
  36. void ins(char *s)
  37. {
  38. int len = strlen(s);
  39. int now = ;
  40. for(int i=;i<len;i++)
  41. {
  42. int key = s[i] - '';
  43. if(t[now].next[key] != -)
  44. {
  45. now = t[now].next[key];
  46. t[now].v ++;
  47. }
  48. else
  49. {
  50. t[now].next[key] = ++t[].v;
  51. now = t[now].next[key];
  52. t[now].v = ;
  53. memset(t[now].next, -, sizeof(t[now].next));
  54. }
  55. }
  56. }
  57.  
  58. int findtrie(char *s)
  59. {
  60. int len = strlen(s);
  61. int now = ,ret = ;
  62. for(int i=;i<len;i++)
  63. {
  64. int key = s[i] - '';
  65. if(t[now].next[key] != -)
  66. {
  67. now = t[now].next[key];
  68. ret = t[now].v;
  69. }
  70. else
  71. return ;
  72. }
  73. return ret;
  74. }
  75.  
  76. int main()
  77. {
  78. int T;
  79. scanf("%d",&T);
  80. while(T--)
  81. {
  82. init();
  83. int n;
  84. scanf("%d",&n);
  85. for(int i=;i<n;i++)
  86. {
  87. scanf("%s",s[i]);
  88. ins(s[i]);
  89. }
  90. int flag = ;
  91. for(int i=;i<n;i++)
  92. if(findtrie(s[i]) > )
  93. {
  94. flag = ; break;
  95. }
  96. printf(flag ? "NO\n" : "YES\n");
  97. }
  98. }
  1.  

字典树Trie Tree的更多相关文章

  1. 字典树(Trie Tree)

    在图示中,键标注在节点中,值标注在节点之下.每一个完整的英文单词对应一个特定的整数.Trie 可以看作是一个确定有限状态自动机,尽管边上的符号一般是隐含在分支的顺序中的.键不需要被显式地保存在节点中. ...

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

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

  3. 字典树trie学习

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

  4. 『字典树 trie』

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

  5. 字典树(Trie)详解

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

  6. 字典树(Trie树)实现与应用

    一.概述 1.基本概念 字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种. 2.基本性质 根节点不包含字符,除根节点外的每一个子节点都包含一个字符 从根节点到某一节点.路径上 ...

  7. [转载]字典树(trie树)、后缀树

    (1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...

  8. Codevs 4189 字典(字典树Trie)

    4189 字典 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 大师 Master 传送门 题目描述 Description 最经,skyzhong得到了一本好厉害的字典,这个字典里 ...

  9. 字典树trie

    字典树经常用于单词搜索,现在网络引擎中也应用了trie树: public class Trie{ private int SIZE = 26; private TrieNode root; Trie( ...

随机推荐

  1. Spring Boot project with static content generates 404 when running jar

    转自:http://stackoverflow.com/questions/21358403/spring-boot-project-with-static-content-generates-404 ...

  2. HDU1114 - Piggy-Bank

    Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. ...

  3. nyoj56-阶乘因式分解(一)

    56-阶乘因式分解(一) 内存限制:64MB时间限制:3000msSpecial Judge: No accepted:6submit:7 题目描述: 给定两个数m,n,其中m是一个素数. 将n(0& ...

  4. Hive sql

    1.DDL操作 1.1 建表 CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_ ...

  5. xunsearch实战经验总结

    一.定义好配置文件(非常关键) a):如果需要做精确搜索建议对字段设定index=self,tokenizer = full,不然xunsearch会对字段做分词处理: b):数字区间搜索需设定 ty ...

  6. Spring中的容器

    1.Spring容器 Spring容器最基本的接口就是BeanFactory, 负责配置,创建和管理bean.我们通常不直接使用BeanFactory接口,而是使用其子接口ApplicationCon ...

  7. 00072_System类

    1.概念 (1)System中代表程序所在系统,提供了对应的一些系统属性信息,和系统操作: (2)System类不能手动创建对象,因为构造方法被private修饰,阻止外界创建对象: (3)Syste ...

  8. 【hiho一下 第十周】后序遍历

    [题目链接]:http://hihocoder.com/problemset/problem/1049 [题意] [题解] 前序遍历的第一个节点; 肯定是整颗树的头结点; 然后在中序遍历中; 得到这个 ...

  9. JAVA的基本数据类型和引用数据类型的区别

        引用数据类型: 类.接口类型.数组类型.枚举类型.注解类型:   基本数据类型和引用数据类型的区别: 基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上: 引用数据类型在被创 ...

  10. [Windows Server]新机子上装老系统·

    硬盘模式改了也得用U大师,然后再PE里装 1.U大师做启动盘 2.拷贝解压后的系统进去 3.用PE自带安装工具