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

应用

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

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

结点的结构体:

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

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

void insert_trie(char *s)
{
int len = strlen(s);
int now = ;
for(int i=;i<len;i++)
{
int key = s[i] - ''; //key的值由字符串字符类型决定
if(t[now].next[key] != -)
{
now = t[now].next[key];
t[now].v ++;
}
else
{
t[now].next[key] = ++t[].v;
now = t[now].next[key];
t[now].v = ;
memset(t[now].next, -, sizeof(t[now].next));
}
}
}
 

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

int find_trie(char *s)
{
int len = strlen(s);
int now = ,ret = ;
for(int i=;i<len;i++)
{
int key = s[i] - '';
if(t[now].next[key] != -)
{
now = t[now].next[key];
ret = t[now].v;
}
else
return ;
}
return ret;
}
 

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

void init()
{
for(int i=;i<=t[].v;i++)
{
if(i) t[i].v = ;
memset(t[i].next, -, sizeof(t[i].next));
}
t[].v = ;
}
 

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

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define EPS 0.00000001
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long ll; const int maxn = ;
typedef struct Trie Trie;
typedef struct Trie* ptr;
struct Trie
{
ptr next[maxn];
int v; //表示一个字典树到此有多少相同前缀的数目
};
ptr root; void init()
{
if(root == NULL)
{
root = (ptr) malloc (sizeof(Trie));
root -> v = ;
for(int j=;j<maxn;j++)
root -> next[j] = NULL;
}
} void Insert(char *s)
{
int len = strlen(s);
ptr now = root;
for(int i=;i<len;i++)
{
int key = s[i] - 'a';
if(now -> next[key] != NULL)
{
now -> next[key] -> v ++;
now = now -> next[key];
}
else
{
ptr tmp = (ptr) malloc (sizeof(Trie));
tmp -> v = ;
for(int j=;j<maxn;j++)
tmp -> next[j] = NULL;
now -> next[key] = tmp;
now = tmp;
}
}
} int findTrie(char *s)
{
int len = strlen(s), ret = ;
ptr now = root;
for(int i=;i<len;i++)
{
int key = s[i] - 'a';
if(now -> next[key] != NULL)
{
now = now -> next[key];
ret = now -> v;
}
else
{
return ;
}
}
return ret;
} int main()
{
init();
char s[];
int flag = ;
while(gets(s) != NULL)
{
if(strlen(s) == )
{
flag = ;
continue;
}
if(!flag) Insert(s);
else cout << findTrie(s) << endl;
}
}

HDU 1671Phone List/要加初始化/

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define EPS 0.00000001
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long ll; const int maxn = ;
const int maxm = ;
struct trie{
int next[maxn];
int v;
}t[maxm];
char s[maxm][]; void init()
{
for(int i=;i<=t[].v;i++)
{
if(i) t[i].v = ;
memset(t[i].next, -, sizeof(t[i].next));
}
t[].v = ;
} void ins(char *s)
{
int len = strlen(s);
int now = ;
for(int i=;i<len;i++)
{
int key = s[i] - '';
if(t[now].next[key] != -)
{
now = t[now].next[key];
t[now].v ++;
}
else
{
t[now].next[key] = ++t[].v;
now = t[now].next[key];
t[now].v = ;
memset(t[now].next, -, sizeof(t[now].next));
}
}
} int findtrie(char *s)
{
int len = strlen(s);
int now = ,ret = ;
for(int i=;i<len;i++)
{
int key = s[i] - '';
if(t[now].next[key] != -)
{
now = t[now].next[key];
ret = t[now].v;
}
else
return ;
}
return ret;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int n;
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%s",s[i]);
ins(s[i]);
}
int flag = ;
for(int i=;i<n;i++)
if(findtrie(s[i]) > )
{
flag = ; break;
}
printf(flag ? "NO\n" : "YES\n");
}
}
 

字典树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. 【BZOJ2733】【HNOI2012】永无乡 - 线段树合并

    题意: Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己的独一无二的重要度,按照重要度可 以将这 n 座岛排名,名次用 1 到 n 来表示.某些岛之间由巨大的桥连接,通 ...

  2. 原生node实现简易留言板

    原生node实现简易留言板 学习node,实现一个简单的留言板小demo 1. 使用模块 http模块 创建服务 fs模块 操作读取文件 url模块 便于path操作并读取表单提交数据 art-tem ...

  3. js中获取宽高

    <script type="text/javascript"> function getWH() { var a = ""; a += " ...

  4. MarkdownPad 2 安装使用之二三事

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50685187 官网:http://ma ...

  5. CF909A Generate Login

    CF909A Generate Login 题意翻译 给定两个用空格分隔的字符串,分别取两字符串的任意非空前缀,将两前缀合并为一个新的字符串,求可行字典序最小的字符串. 题目描述 The prefer ...

  6. POJ 2470 Ambiguous permutations(简单题 理解题意)

    [题目简述]:事实上就是依据题目描写叙述:A permutation of the integers 1 to n is an ordering of these integers. So the n ...

  7. Android Touch事件分发过程

    虽然网络上已经有非常多关于这个话题的优秀文章了,但还是写了这篇文章,主要还是为了加强自己的记忆吧,自己过一遍总比看别人的分析要深刻得多.那就走起吧. 简单演示样例 先看一个演示样例 : 布局文件 : ...

  8. 安卓项目开发实战(1)--首页顶部菜单BAR实现

    从今天開始,我将開始自己手写一个星座运势的项目,星座运势的数据来源採用MYAPI的星座数据,client全然自己实现. 这个系列主要是讲project中主要界面的布局展示和一些项目中的难点解析.因为本 ...

  9. Unity3D 人形血条制作小知识

    这几天用Unity3D做个射击小游戏,想做个人形的血条.百思不得其解,后来问了网上的牛牛们,攻克了,事实上挺简单的,GUI里面有个函数DrawTextureWithTexCoords就能够实现图片的裁 ...

  10. Android——隐藏输入法的小技巧

    今天偶然在百度地图提供的DEMO里看到这样一段代码.认为确实是个小技巧,就写下来分享一下. 针对的问题: 我们在开发android界面的时候,常常使用EditText控件.然后每次进入这个页面的时候, ...