什么是trie?

百度百科

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

trie有什么用处?

①进行快速的查找字符串是否存在

②进行快速的字符串的前缀和的相关的性质的查询

如何实现trie?

导言

trie是靠二维数组进行存储的,其中trie[a][b]=c,指的是a的第b个孩子的编号是c。特别的trie是用边来存储字符而并不是节点!编号代表的是a-z的26个字母中的第几个字母所以编号是从0-25。

百度百科的图片

①insert函数

insert函数代表着插入操作。如何实现呢?

(1)把需要插入的string拆分成一个又一个的单个的字符进行操作。并且把rt初始化为0

int rt=0;
for(int i=0;i<a.size();i++)
{
//....
}

(2)计算id编号(注意这个地方是-'a'不是-'0')

int id=a[i]-'a';

(3)循环判断当前的父节点是不是存在一条以id编号的边,如果不存在那么,添加一个这样的边并且把子节点赋予一个编号

if(!trie[rt][id])
trie[rt][id]=++tot;

(4)将rt层层递进

rt=trie[rt][id];

insert函数完整代码

void insert(string a)
{
int rt=0;
for(int i=0;i<a.size();i++)
{
int id=a[i]-'a';
if(!trie[rt][id])
trie[rt][id]=++tot;
rt=trie[rt][id];
}
}

②search函数

search函数代表着查询的操作,这里我们查询当前前缀是不是在树中,当然trie可以做很多别的操作,结合insert函数,如何实现?

(1)(2)同insert函数

  int rt=0;
for(int i=0;i<a.size();i++)
{
int id=a[i]-'a';
//.....
}

(3)查询相应的编号的边是不是这个父节点的儿子,如果不是那么返回0

if(!trie[rt][id])
return 0;

(4)层层递进同insert

rt=trie[rt][id];

(5)如果这个字符串能安全的走出循环,那么就返回1,说明这个前缀是存在的

search函数完整代码

int search(string a)
{
int rt=0;
for(int i=0;i<a.size();i++)
{
int id=a[i]-'a';
if(!trie[rt][id])
return 0;
rt=trie[rt][id];
}
return 1;
}

trie模板完整代码(注意此处的map效率过慢,应该直接开数组为妙)

#include <bits/stdc++.h>
using namespace std;
map<int,map<int,int> > trie;
map<int,int> sum;
int tot;
void insert(string a)
{
int rt=0;
for(int i=0;i<a.size();i++)
{
int id=a[i]-'a';
if(!trie[rt][id])
trie[rt][id]=++tot;
rt=trie[rt][id];
}
}
int search(string a)
{
int rt=0;
for(int i=0;i<a.size();i++)
{
int id=a[i]-'a';
if(!trie[rt][id])
return 0;
rt=trie[rt][id];
}
return 1;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
string a;
cin>>a;
insert(a);
}
for(int i=0;i<m;i++)
{
string a;
cin>>a;
if(search(a))
cout<<"YES\n";
else
cout<<"NO\n";
}
}

拓展

①查询相应前缀所包含的字符串的数量(hdu 1251 统计难题)

只需要在insert函数中设定一个sum数组,保存每个节点遍历过的次数,即sum[trie[rt][id]]++,然后在search函数中寻找到字符串最后的节点返回sum[rt]即可。只要中间出现没有在树中的字符直接return0

②查询相应的单词是否在树中

只需要在insert函数中设置一个记录词尾的数组即可,然后search函数中找到最后如果这个词尾存在的话那么就是存在否则就是不存在

trie字典树模板浅析的更多相关文章

  1. [trie]字典树模板

    #include<bits/stdc++.h> using namespace std; typedef long long ll; struct trie{ int count; tri ...

  2. CH 1601 - 前缀统计 - [字典树模板题]

    题目链接:传送门 描述给定 $N$ 个字符串 $S_1,S_2,\cdots,S_N$,接下来进行 $M$ 次询问,每次询问给定一个字符串 $T$,求 $S_1 \sim S_N$ 中有多少个字符串是 ...

  3. hdu1521(字典树模板)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1251 题意: 中文题诶~ 思路: 字典树模板 代码1: 动态内存, 比较好理解一点, 不过速度略慢, ...

  4. Trie 字典树,hdu1251

    参考博客:https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html 字典树就是单词树,顺着一条路径到达终止结点就形成一个单词,该单词的前缀包含在这 ...

  5. 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)

    萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...

  6. Trie字典树 动态内存

    Trie字典树 #include "stdio.h" #include "iostream" #include "malloc.h" #in ...

  7. 算法导论:Trie字典树

    1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tr ...

  8. 字典树模板题(统计难题 HDU - 1251)

    https://vjudge.net/problem/HDU-1251 标准的字典树模板题: 也注意一下输入方法: #include<iostream> #include<cstdi ...

  9. 标准Trie字典树学习二:Java实现方式之一

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! 系列文章: 1. 标准Trie字典树学习一:原理解析 2.标准T ...

随机推荐

  1. 常用经典SQL语句大全完整版--详解+实例 《来自网络,很全没整理,寄存与此》

    常用经典SQL语句大全完整版--详解+实例 下列语句部分是Mssql语句,不可以在access中使用. SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML ...

  2. 杂项-Java:JSP

    ylbtech-杂项-Java:JSP 1.返回顶部 1. JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它是由Sun Micros ...

  3. Centos7 配置防火墙 firewall

    一.firewall 1.从CentOS7开始,默认使用firewall来配置防火墙,没有安装iptables(旧版默认安装). 2.firewall的配置文件是以xml的格式,存储在 /usr/li ...

  4. 【转载】Java - Wait & Notify

    [本文转自]http://www.cnblogs.com/dolphin0520/p/3920385.html 这三个方法的文字描述可以知道以下几点信息: 1)wait().notify()和noti ...

  5. bzoj 1622: [Usaco2008 Open]Word Power 名字的能量【模拟】

    模拟即可,注意包含可以是不连续的 方便起见读入的时候全转成小写 #include<iostream> #include<cstdio> using namespace std; ...

  6. HTML 5.1 -- 14项新增功能及如何使用

    最近太忙了 过完年来 连续的加班让我筋疲力尽,今天终于把东西交了,抽空来点干货吧! 1. 响应式图像 W3C 引入了一些功能特性,无需使用 CSS 就可以实现响应式图像.它们是 … srcset 图像 ...

  7. linux下jdk环境变量配置深度分析----解决环境变量不生效的问题

    1.linux下jdk环境变量配置 是否需要配置环境变量,主要看java -version 显示的版本是否为你期望的版本 1.1 不需要配置环境变量的情况 使用java -version查看,版本显示 ...

  8. Nginx(一) 安装基于centos7

    1.   nginx介绍 1.1. 什么是nginx Nginx是一款高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.由俄罗斯的程序设计师Igor Sysoev所开 ...

  9. 【题解】自行车比赛 [AHOI2016] [P2777]

    [题解]自行车比赛 \([AHOI2016]\) \([P2777]\) 逼自己每天一道模拟题 传送门:自行车比赛 \([AHOI2016]\) \([P2777]\) [题目描述] 比赛中一共有 \ ...

  10. spring cloud config搭建说明例子(二)-添加eureka

    添加注册eureka 服务端 ConfigServer pom.xml <dependency> <groupId>org.springframework.cloud</ ...