最近学习了一下关于Trie的一些姿势,感觉很实用。

终于不用每次看到字符串判重等操作就只想到hash

关于Trie的定义,来自百度百科

在计算机科学中,Trie,又称前缀树或字典树,是一种有序树状的数据结构,用于保存关联数组,其中的键通常是字符串。

说的有点高级,我们不要管它,可以看这样一张图:

这棵Trie中的单词共有:his,he,her,me,your

就是从根节点一直到某个有end(结尾)标记的点

可以发现,Tire其实就是把一些字符串的公用前缀字符存储了下来

Tire的实现更是简单:

  1. 建立一棵Trie,初始时只有一个空的根节点(编号为0)

  2. 每当插入或删除时,如果当前字符在之前的操作中已经建立,然后直接利用即可,否则新建立一个节点并让上一个节点连上它

  3. 当一个字符串结束时,给该节点做个记号,同时也可存储些其它的信息

具体的实现方法也有两种:邻接表邻接矩阵

在Trie中,显然用邻接矩阵是很快的,但空间的开销可能较大,如果题目说明范围,那么空间允许的情况下可以使用

邻接表还是一样,比较省空间(毕竟要多少开多少)

这里用一道板子题来理解一下:

hihocoder 1366 : 逆序单词

邻接矩阵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的一些算法的更多相关文章

  1. [算法]从Trie树(字典树)谈到后缀树

    我是好文章的搬运工,原文来自博客园,博主July_,地址:http://www.cnblogs.com/v-July-v/archive/2011/10/22/2316412.html 从Trie树( ...

  2. Trie树的创建、插入、查询的实现

    原文:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28977986&id=3807947 1.什么是Trie树 Tr ...

  3. Aho-Corasick算法、多模正则匹配、Snort入门学习

    希望解决的问题 . 在一些高流量.高IO的WAF中,是如何对规则库(POST.GET)中的字符串进行多正则匹配的,是单条轮询执行,还是多模式并发执行 . Snort是怎么组织.匹配高达上千条的正则规则 ...

  4. [转载]字典树(trie树)、后缀树

    (1)字典树(Trie树) Trie是个简单但实用的数据结构,通常用于实现字典查询.我们做即时响应用户输入的AJAX搜索框时,就是Trie开始.本质上,Trie是一颗存储多个字符串的树.相邻节点间的边 ...

  5. trie树(前缀树)

    问题描述:   Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优 ...

  6. Trie树(字典树) 最热门的前N个搜索关键词

    方法介绍 1.1.什么是Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优 ...

  7. 双数组trie树的基本构造及简单优化

    一 基本构造 Trie树是搜索树的一种,来自英文单词"Retrieval"的简写,可以建立有效的数据检索组织结构,是中文匹配分词算法中词典的一种常见实现.它本质上是一个确定的有限状 ...

  8. 从Trie树(字典树)谈到后缀树

    转:http://blog.csdn.net/v_july_v/article/details/6897097 引言 常关注本blog的读者朋友想必看过此篇文章:从B树.B+树.B*树谈到R 树,这次 ...

  9. Trie树 - 字典树

    1.1.什么是Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是最大限 ...

随机推荐

  1. vue与原生混合开发

    前段时间,做了一个混合开发的项目,主要是以vue框架开发h5页面,使用cordova作为中间沟通桥梁,实现了h5与安卓.iOS的混合开发,由于从事iOS开发,h5也是刚接触不久,很多深入原理还不太清楚 ...

  2. Spring Boot -05- 多模块结构项目构建与测试(详细图文教程)IDEA 版

    Spring Boot -05- 多模块结构项目构建与测试(详细图文教程)IDEA 版 百度很多博客都不详细,弄了半天才把 Spring Boot 多模块项目构建开发整的差不多,特地重新创建配置,记录 ...

  3. kafka入门1:安装及配置

    1下载 官方下载地址:https://kafka.apache.org/downloads 案例使用版本:kafka_2.11-1.1.0.tgz 2上传服务器 使用ftp工具将压缩包放置到服务器上 ...

  4. C#中使用反射遍历一个对象属性和值以及百分数

    对某个类的实例化对象, 遍历获取所有属性(子成员)的方法(采用反射): using (var context = new YZS_TRAEntities()) { ).FirstOrDefault() ...

  5. IIS日志导致磁盘被占满

    某服务器只部署了个IIS,应用目录都在D盘,可C盘97.5GB空间却被占满了. 将系统文件,隐藏文件全部显示,再选中所有的C盘文件及文件夹查看容量只有19GB. 既然只部署了IIS,那自然就怀疑到了I ...

  6. [CENTOS7] 将域群组加入到Sudoer里

    文章来源:https://derflounder.wordpress.com/2012/12/14/adding-ad-domain-groups-to-etcsudoers/ Adding AD d ...

  7. [Spark SQL_1] Spark SQL 配置

    0. 说明 Spark SQL 的配置基于 Spark 集群搭建  && Hive 的安装&配置 1. 简介 Spark SQL 是构建在 Spark Core 模块之上的四大 ...

  8. 关于使用python的open函数时报No Such File or DIr的错误

    我写的代码如下: def createFileWithFileName(localPathParam,fileName): totalPath=local_url+'\\'+fileName if n ...

  9. SmartUpload相关类的说明

    ㈠ File类 这个类包装了一个上传文件的所有信息.通过它,可以得到上传文件的文件名.文件大小.扩展名.文件数据等信息. File类主要提供以下方法: 1.saveAs作用:将文件换名另存. 原型: ...

  10. CSS布局(三) 布局模型

    布局模型 在网页中,元素有三种布局模型:1.流动模型(Flow) 默认的2.浮动模型 (Float)3.层模型(Layer) 1.流动模型(Flow) 流动(Flow)模型是默认的网页布局模式.也就是 ...