字典树

原创 2018年04月16日 15:28:32

字典树(trie)这个东西真的是特别好理解,先看一下它的模板题吧:

有n个单词,一个句子,问在句子中有多少个单词出现过。

字典树,顾名思义,肯定查询功能特别发达,那么它具体怎么实现呢,在字典树中,有一个root节点,也就是整棵树的根,字典树的每一个节点(包括root)都向下连出了26条边,也就是对应的26个字母(注意!字典树中字母是记录在边上的),但每一条边下不一定都有儿子,于是,对于这道例题,可以将所有单词建一棵字典树,在每一个节点上多设置一个end变量,表示以这个节点与它父亲之间的边上的字母作为最后一个字母的单词的数量,换一种说法就是能以root到这个节点的路径上的所有字母按顺序组合成的单词数量,虽然end的意思我琢磨了很久,但我觉得还是没解释清楚啊。。那我用一幅图来解释吧

假如给出以下单词

love

lol

loop

apple

app

air

那么构建出来的字典树就是这样的(红字为end的值):


这样总明白了吧。。。

 为什么我要如此强调end这个东西呢,因为有关字典树的题一般都会用到它,那么,查询就很简单了,每次将一个单词与这颗字典树匹配一次,字典树先从root开始,单词s先从第1个字母开始,看root是否有s[1]这个儿子,有就往下走,一旦出现没有的情况,说明匹配失败,那接下来看代码吧(代码可能有误,欢迎指正。。):

#include <cstdio>
#include <cstring>

struct node{int son[27],end;};
node tree[100010];//字典树 
int n,len=1;//len记录树中节点数量 
int ch(char x){return x-'a'+1;}//将a~z转成1~26来存 
char chb(int x){return x+'a'-1;}
void build(char ss[],int y)//构造字典树 
{
	int now=0;
	for(int i=0;i<y;i++)
	{
		if(tree[now].son[ch(ss[i])]!=-1)now=tree[now].son[ch(ss[i])];//如果有ss[i]这个儿子,就继续往下走 
		else//否则新建一个儿子 
		{
			len++;
			tree[len].end=0;
			tree[now].son[ch(ss[i])]=len;
			now=len;
		}
	}
	tree[now].end++;//表示以此结尾的单词数量+1 
}
char w[10010];//文本串 

int main()
{
	scanf("%d",&n);
	memset(tree[0].son,-1,sizeof(tree[0].son));//初始化root节点 
	tree[0].end=0;
	for(int i=1;i<=n;i++)
	{
		char s[1010];
		scanf("%s",s);
		build(s,strlen(s));
	}
	int ans=0;
	getchar();
	gets(w);
	int m=strlen(w);
	for(int i=0;i<m;i++)
	{
		if(w[i]>='a'&&w[i]<='z')//假如遇到了单词 
		{
			int now=0;
			while(tree[now].son[ch(w[i])]!=-1)//假如有这个儿子 
			{
				now=tree[now].son[ch(w[i])];i++;//往下走 
				if(tree[now].end!=0&&(w[i]==' '||i==m))//假如发现了一个单词 
				{
					ans+=tree[now].end;
					tree[now].end=0;
				}
				if(i==m||w[i]<'a'||w[i]>'z')break;
			}
			while(w[i]>='a'&&w[i]<='z')i++;//如果前面匹配失败了,那么后面连着的字母也没用了 
		}
	}
	printf("%d",ans);
} 
/*测试数据 
5
love
lol
like
hot
hole
dog like hot hole and love hot dog,lollll

ans=4
*/


字典树数组实现

字典树是一种很实用也相对好理解的数据
  • u013588639
  • u013588639
  • 2014-08-06 21:04:05
  • 1692

字典树的指针模板与数组模板

第一个模板便是指针字典树的模板: #include #include #include const int MAX=26; struct Tire{ Tire *next[MAX]; int v...
  • qq_18661257
  • qq_18661257
  • 2015-03-06 18:12:59
  • 1785

字典树简介、应用以及与哈希表的比较

题目要求:1、设计并实现N-array trie,包括初始化,查找,插入,删除等。 2、应用trie结构实现文本文档的索引化,首先扫描文本文档,然后利用trie结构记录单词行号,最后在trie上实现查...
  • liyongqi_
  • liyongqi_
  • 2017-05-04 22:07:00
  • 529

【字典树】字典树的创建(入门详细介绍)

Part one【何谓字典树】又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它...
  • thesprit
  • thesprit
  • 2016-07-29 15:12:16
  • 2448

trie树(字典树)java实现

public class Trie{ private Node root; public Trie(){ root = new Node(' '); } ...
  • u012572955
  • u012572955
  • 2016-05-06 14:21:23
  • 779

一个Trie字典树的简单实现

// 字典树.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include u...
  • zy_dreamer
  • zy_dreamer
  • 2013-06-21 10:56:46
  • 969

【面经笔记】trie树/字典树

字典树构造及其优化与应用字典树的核心就是空间换时间,利用字符串的公共前缀来避免无谓的字符串比较,降低查询时间。对于统计/查询单词的问题,可将哈希表改进为字典树提升效率。性质: - 根结点不包含字符,...
  • xiaxzhou
  • xiaxzhou
  • 2017-07-09 20:09:56
  • 500

字典树题目总结

Trie 就好比维护了一个字典,可以在这个字典里插入删除字符串,也可以查询一个字符串是否在字典中。Trie的插入查找删除复杂度都是O(m)的,其中m为待插入串的长度。 Trie的原理是利用字符串...
  • yew1eb
  • yew1eb
  • 2014-02-17 20:19:50
  • 2669

字典树数组形式写法

第一题: Remember the Word Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %l...
  • DoJintian
  • DoJintian
  • 2015-08-05 17:04:41
  • 1178

Java实现字典树TrieTree

为了准备阿里的网上笔试,这几天回顾了数据结构.看到字典树时,突然发现四六级的高频词可以用字典树找出来的.(应该不会是一个一个数出来的吧....) 构造字典树的过程如下: 1.首先确定树节点需要用怎么样...
  • lc0817
  • lc0817
  • 2015-08-19 13:04:45
  • 3750
收藏助手
不良信息举报
您举报文章:字典树
举报原因:
原因补充:

(最多只允许输入30个字)