关于Trie的一些算法
最近学习了一下关于Trie的一些姿势,感觉很实用。
终于不用每次看到字符串判重等操作就只想到hash了
关于Trie的定义,来自百度百科
在计算机科学中,Trie,又称前缀树或字典树,是一种有序树状的数据结构,用于保存关联数组,其中的键通常是字符串。
说的有点高级,我们不要管它,可以看这样一张图:

这棵Trie中的单词共有:his,he,her,me,your
就是从根节点一直到某个有end(结尾)标记的点
可以发现,Tire其实就是把一些字符串的公用前缀字符存储了下来
Tire的实现更是简单:
建立一棵Trie,初始时只有一个空的根节点(编号为0)
每当插入或删除时,如果当前字符在之前的操作中已经建立,然后直接利用即可,否则新建立一个节点并让上一个节点连上它
当一个字符串结束时,给该节点做个记号,同时也可存储些其它的信息
具体的实现方法也有两种:邻接表和邻接矩阵
在Trie中,显然用邻接矩阵是很快的,但空间的开销可能较大,如果题目说明范围,那么空间允许的情况下可以使用
邻接表还是一样,比较省空间(毕竟要多少开多少)
这里用一道板子题来理解一下:
邻接矩阵CODE
#include<iostream>
#include<string>
using namespace std;
const int N=50005;
struct node
{
bool end;
int next[30];
}trie[N<<4];
string s;
int n,ans,cnt;
inline bool find(string s)
{
int now=0,len=s.size();
for (register int i=0;i<len;++i)
{
if (trie[now].next[s[i]-'a'+1]) now=trie[now].next[s[i]-'a'+1]; else return 0;
if (i==len-1) return trie[now].end;
}
}
inline void insert(string s)
{
int now=0,len=s.size();
for (register int i=0;i<len;++i)
{
if (trie[now].next[s[i]-'a'+1]) now=trie[now].next[s[i]-'a'+1]; else trie[now].next[s[i]-'a'+1]=++cnt,now=cnt;
if (i==len-1) trie[now].end=1;
}
}
int main()
{
register int i;
for (cin>>n,i=1;i<=n;++i)
{
cin>>s;
string rs(s.rbegin(),s.rend());
if (find(rs)) ++ans;
insert(s);
}
cout<<ans;
return 0;
}
邻接表CODE
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
const int N=50005;
struct node
{
bool end;
char ch;
}trie[N<<4];
struct edge
{
int to,next;
}link[N<<4];
string s;
int head[N<<4],n,ans,cnt;
inline void add(int x,int y,char z)
{
link[y].to=y; trie[y].ch=z; link[y].next=head[x]; head[x]=y;
}
inline bool find(string s)
{
int now=0,len=s.size();
for (register int i=0;i<len;++i)
{
bool flag=0;
for (register int j=head[now];j!=-1;j=link[j].next)
if (trie[link[j].to].ch==s[i]) { flag=1; now=link[j].to; break; }
if (!flag) return 0;
if (i==len-1) return trie[now].end;
}
}
inline void insert(string s)
{
int now=0,len=s.size();
for (register int i=0;i<len;++i)
{
bool flag=0;
for (register int j=head[now];j!=-1;j=link[j].next)
if (trie[link[j].to].ch==s[i]) { flag=1; now=link[j].to; break; }
if (!flag) add(now,++cnt,s[i]),now=cnt;
if (i==len-1) trie[now].end=1;
}
}
int main()
{
register int i;
memset(link,-1,sizeof(link));
memset(head,-1,sizeof(head));
for (cin>>n,i=1;i<=n;++i)
{
cin>>s;
string rs(s.rbegin(),s.rend());
if (find(rs)) ++ans;
insert(s);
}
cout<<ans;
return 0;
}
关于Trie的一些算法的更多相关文章
- [算法]从Trie树(字典树)谈到后缀树
我是好文章的搬运工,原文来自博客园,博主July_,地址:http://www.cnblogs.com/v-July-v/archive/2011/10/22/2316412.html 从Trie树( ...
- Trie树的创建、插入、查询的实现
原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28977986&id=3807947 1.什么是Trie树 Tr ...
- Aho-Corasick算法、多模正则匹配、Snort入门学习
希望解决的问题 . 在一些高流量.高IO的WAF中,是如何对规则库(POST.GET)中的字符串进行多正则匹配的,是单条轮询执行,还是多模式并发执行 . Snort是怎么组织.匹配高达上千条的正则规则 ...
- [转载]字典树(trie树)、后缀树
(1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...
- trie树(前缀树)
问题描述: Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优 ...
- Trie树(字典树) 最热门的前N个搜索关键词
方法介绍 1.1.什么是Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优 ...
- 双数组trie树的基本构造及简单优化
一 基本构造 Trie树是搜索树的一种,来自英文单词"Retrieval"的简写,可以建立有效的数据检索组织结构,是中文匹配分词算法中词典的一种常见实现.它本质上是一个确定的有限状 ...
- 从Trie树(字典树)谈到后缀树
转:http://blog.csdn.net/v_july_v/article/details/6897097 引言 常关注本blog的读者朋友想必看过此篇文章:从B树.B+树.B*树谈到R 树,这次 ...
- Trie树 - 字典树
1.1.什么是Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是最大限 ...
随机推荐
- art-template模板应用
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- React Native常用第三方组件汇总--史上最全 之一
React Native 项目常用第三方组件汇总: react-native-animatable 动画 react-native-carousel 轮播 react-native-countdown ...
- [Android] 设置AlertDialog打开后不消失
最近项目收尾,一堆bug要改,还要对用户操作体验做一些优化,也是忙的不行.周末难得清闲,出去逛逛,看看风景,还好因为习大大要来,南京最近的天气还不错,只是苦了当地的不少农民工,无活可干,无钱可拿.想想 ...
- Python+Selenium笔记(五):生成测试报告
#HTMLTestRunner代码修改参考 微微微笑 的说明,下面是链接,这个已经说的很详细了 https://www.cnblogs.com/miniren/p/5301081.html (一) 前 ...
- Windows安装PostgreSQL数据库 无法初始化数据库问题
背景 由于项目的需要,使用PostgreSQL数据库,因此在Windows上安装PostgreSQL数据库.但是在安装后,无法访问本地数据库,这个时候查看/data目录,没有任何文件.而且安装过程中, ...
- Oracle EBS FTP显示无法与某IP 连接
首先 用root用户登录 如果可以登录 那么应该是权限的问题 这里选择 方法二:修改 /etc/sudoers 文件,找到下面一行,在root下面添加一行,如下所示: ## Allow root to ...
- TMOUT优化终端超时
有时候,管理员终端登陆了系统,如果离开没有退出账户,则会有安全隐患存在,因此需要优化终端超时. 设置终端超时: export TMOUT=10 永久生效: echo "export TMOU ...
- 【转】Java学习---volatile 关键字
[原文]https://www.toutiao.com/i6591422029323305480/ 前言 不管是在面试还是实际开发中 volatile 都是一个应该掌握的技能. 首先来看看为什么会出现 ...
- win7X64位安装mysql-5.7.16
今天尝试在win7系统中安装mysql,发现过程有点复杂,不过还好已经成功安装,写个博客纪念一下,顺便可以帮助大家. 1.在官网上面下载mysql, 注意:一定要下载对应的版本,第一次下载的是最下面一 ...
- MySQL主从复制日常管理维护篇
日常工作中,我们需要经常进行一些监控和管理维护工作,以便能及时发现一些复制中的问题,并尽快解决,以此来保证复制能够正常工作 1.查看从库状态 MySQL [(none)]> show slave ...