什么是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. 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) S Surf

    SurfNow that you've come to Florida and taken up surng, you love it! Of course, you've realized that ...

  2. vue 基础知识 随笔

    window.localStorage.gettItem("someItem"||[])//如果localStorage中的someItem不存在就返回一个空数组 window.l ...

  3. GitHub上README.md教程(copy)

    [说明:转载于http://blog.csdn.net/kaitiren/article/details/38513715] 最近对它的README.md文件颇为感兴趣.便写下这贴,帮助更多的还不会编 ...

  4. HTTP请求 响应状态码

      1.请求响应方式       get是从服务器上获取数据,post是向服务器传送数据.get 数据在地址栏中明文的形式发送, post则不是,传递的数据比get多 据RFC2616标准(现行的HT ...

  5. jQuery 表格隔行变色插件

    jQuery提供了用于扩展jQuery功能的方法,即jQuery.fn.extend()方法和jQuery.extend()方法. 基本的JS框架代码如下: ;(function($) { $.fn. ...

  6. 牛客OI周赛2-提高组

    A.游戏 链接:https://www.nowcoder.com/acm/contest/210/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语 ...

  7. [App Store Connect帮助]四、添加 App 图标、App 预览和屏幕快照(1)App Store 图标、App 预览和屏幕快照概述

    您可以为您的 App Store 产品页提供有关您 App 的 App Store 图标.三个 App 预览和十张屏幕快照. App Store 图标 您必须提供一个 App Store 图标,用于在 ...

  8. deepin 安装版本管理工具

    在Linux下我们可以使用RapidSVN.RapidSVN是一款轻量级的免费.开源 SVN 客户端,相比tortoise svn它更加小巧而且占系统资源少运行速度快. 一:安装RapidSVN版本控 ...

  9. Winform执行CMD命令

    1.首先分享CmdHelper类: using System; using System.Collections.Generic; using System.Text; using System.Di ...

  10. LeetCode 要记得一些小trick

    最近搞了几场编程比赛,面试题或者是LeetCode周赛.每次都不能做完,发现时间不够用. 看了别人的代码才知道,同样实现相同的功能,可能别人只需要用一个恰当的函数,就会比自己少些不少代码,争得了时间. ...