关于Trie的一些算法

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

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

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

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

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

1251070-20180420201047817-52836826.png

这棵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;
}

转载于:https://www.cnblogs.com/cjjsb/p/8835042.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414264.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用nginx搭建https服务器

最近在研究nginx&#xff0c;整好遇到一个需求就是希望服务器与客户端之间传输内容是加密的&#xff0c;防止中间监听泄露信息&#xff0c;但是去证书服务商那边申请证书又不合算&#xff0c;因为访问服务器的都是内部人士&#xff0c;所以自己给自己颁发证书&#xff0c;忽略掉…

分布式配置中心阿波罗的搭建与客户端的应用

为了统一管理微服务配置文件&#xff0c;实现动态化刷新配置文件&#xff0c;常见的两种方式为阿波罗、SpringCloudConfig&#xff0c;关于两者主要区别是&#xff1a; 阿波罗配置文件存放在数据库中&#xff0c;SpringCloudConfig存放在Git里面 一、搭建过程 本篇主要演示阿波…

PHP攻击防御

原文地址 有个朋友网站被攻击&#xff0c;刚好我们的网站有比较全面的攻击防御&#xff0c;了解了一下自己网站的防御&#xff0c;再上网搜了一些文章来看&#xff0c;觉得上面的文章写得很全面&#xff0c;特此备份。留着以后自己忘记的时候看看。

毕业一年的大专生程序员工作总结(java后台)

文章导读 一、回眸过去 – 闲扯的话 – 零碎的技术二、经验总结 – 沟通交流 – 贵在坚持 – 合理规划三、展望未来 – 积累行业背景 – 学习清单四、最后补充 一、 回牟过去 1、闲扯的话 大专生毕业一年工作总结&#xff0c;谈不上予人借鉴&#xff0c;算是对自己过去一年…

mysql自带加密解密字符集问题

由于公司业务需要&#xff0c;需要对已有的数据进行加密&#xff0c; 由于数据加密之后需要可逆的解密&#xff0c;最先考虑使用encode&#xff0c;decode函数&#xff1b;在实际使用的过程遇到加密数据解密之后得不到原本的值&#xff0c;后发现是由于字符集不正确&#xff0c…

重温类加载机制

前言 我们在学习 java 基础的时候&#xff0c;从宏观上了解一个类到运行大致是&#xff1a;.java 文件通过 javac 编译器编译得到 .class 文件&#xff0c;在用到该类时&#xff0c;jvm 会加载该 class 文件&#xff0c;并创建对应的 class 对象&#xff0c;将 class 文件加载…

微信团队分享:微信移动端的全文检索多音字问题解决方案

本文来自微信开发团队WeMobileDev公众号的技术分享。 1、前言 微信的移动客户端全文搜索中的多音字问题一直是搜索体验的痛点之一。微信客户端全文搜索在上线以后&#xff0c;也经常收到用户关于多音字问题的反馈。所以&#xff0c;微信全文搜索中的多音字搜索成了一个迫切需要…

PHP编译不成功

早上开机的时候运行本地网站&#xff0c;蹦出一个error: ERROR:syntax error, unexpected 92 (T_CONSTANT_ENCAPSED_STRING), expectin懵&#xff0c;昨天下班前不是还好好的吗&#xff08;其实我不知道下班前是不是好好的&#xff0c;因为下班前没跑程序好尴尬&#xff09;&am…

201571030128/201571030118《小学四则运算练习软件软件需求说明》结对项目报告

一、以实验二个人项目、实验三结对项目所开发的小学生四则运算练习软件作为原型&#xff0c;实施小学生四则运算练习软件用户调研活动具体过程。 1、真实的调研对象 对象性别年龄身份刘老师女23小学数学实习老师杨同学男12小学五年级学生杨家长女35杨同学的家长何老师男24小学数…

QQ互联登陆(Java)

一、准备部分 1、账户注册 腾讯开放平台网址: https://connect.qq.com/index.html 首先需要到开放平台注册QQ互联开发者身份。注册之后创建一个网站应用&#xff0c;注意&#xff0c;需要备案成功的域名才可申请。 2、应用审核 审核通过后如下图所示&#xff0c;审核通过后可以…

动静分离-静态资源缓存控制

一、静态资源服务与动态资源服务的区别 首先动静分离非前后端分离&#xff0c;关于两者的介绍如下&#xff1a; 动静分离&#xff1a;动态资源(jsp、ftl)与静态资源(js、img、css)分开前后端分离&#xff1a;接口与视图分开独立开发部署二、为什么静态资源需要实现CDN内容加速 …

分布式session共享

一、前言 为什么会出现session共享问题&#xff1f; 客户端与服务器交互时会产生唯一的sessionid用于标记用户&#xff0c;但是在分布式架构中&#xff0c;如果还是采用 session 的方式&#xff0c;用户发起请求&#xff0c;通过 nginx 做请求转发时&#xff0c;并不知道是转发…

InnoDB锁问题

InnoDB锁问题 InnoDB与MyISAM的最大不同有两点&#xff1a;一是支持事务&#xff08;TRANSACTION&#xff09;&#xff1b;二是采用了行级锁。行级锁与表级锁本来就有许多不同之处&#xff0c;另外&#xff0c;事务的引入也带来了一些新问题。下面我们先介绍一点背景知识&#…