Trie树结构与实现
来源:互联网 发布:java 保存文本文件 编辑:程序博客网 时间:2024/05/17 00:58
Trie树结构与实现
概述
在平时使用搜索引擎或者一些其他工具时,常会有一些智能提示,或许我们需要搜索的内容并不存在,但这些工具都会尽量选择前缀尽可能相似的结果给我们。这里使用到的前缀匹配,大多则是使用Trie树进行处理。
Trie树基本定义
Trie树,又被称为前缀树或字典树,与其用途有关,Trie树是一种有序树,用于保存关联数组,其中的Key通常是字符串。与二叉查找树不同,Key并不直接存储在Trie树种,而是由节点在树中位置决定。一个节点的所有子节点具有相同前缀,也就是这个节点对应的字符串,即Key,根节点对应空字符串。
上图即为一颗Trie树,由关键字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 构造而成。先来说明Trie树的特性:
- 根节点不包含任何字符,除根节点外,任一节点都包含一个字符;
- 从根节点到任一子节点的路径上,连接之后可以得到一个字符串,为该节点对应的字符串;
- 每个节点的子节点包含的字符必须互不相同。
由上图不难发现,若两个关键字具有相同前缀,那到达完整关键字节点的路径必有一段是相同的,所以Trie树的一个应用可以用来求解多关键字的最长公共前缀。下面则是求解最长公共前缀具体的代码实现,相关需要注意的点在注释中可以找到。
实现
typedef struct trie_tree { int cnt; // 当前节点所代表字符出现次数 struct trie_tree *next[26]; // 记录子节点的指针数组 trie_tree() : cnt(0) { for (int i = 0; i < 26; ++i) { next[i] = 0; } }} trie_t;
指针数组大小为26,仅是用于简单表示关键字由26个小写字母组合的情况,这个可以根据问题去做修改。根据需要求解的问题的不同,也可以针对结构体做一些相应修改,如词频统计或许需要一个bool值来判别是否为一个关键字。
void trie_create(const std::string &str, trie_t *root){ int i; int len = (int) str.length(); trie_t *cur = root; for (i = 0; i < len; ++i) { if (cur->next[str[i] - 'a'] == 0) { cur->next[str[i] - 'a'] = new trie_t(); } cur = cur->next[str[i] - 'a']; ++(cur->cnt); }}
对于一个字符串将其添加进Trie树,若遇到不存在表示某字符的节点,则应创建一个。
std::string trie_search_lcp(trie_t *root, size_t strs_cnt, size_t min_len){ std::string res; trie_t *cur = root; int i; int index; int scnt; // 表示子节点个数 while (cur != 0) { scnt = 0; for (i = 0; i < 26; ++i) { // 寻找next路径,以构成最长公共前缀 if (cur->next[i] != 0) { ++scnt; index = i; } } if (strs_cnt == 0) { // 字符串集合为空,最长公共前缀为空 return res; } else if (strs_cnt == 1) { // 字符串集合仅有1个元素,最长公共前缀即为该元素 if (scnt == 1) { // next仅有1个节点 res.push_back('a' + index); cur = cur->next[index]; } else { // next无节点 cur = 0; } } else { // 字符串集合有多于1个元素 if (scnt == 1) { // next仅有1个节点 // 节点字符出现次数与集合元素数量相等 if (cur->next[index]->cnt == strs_cnt) { // 最长公共前缀的最大长度一定小于等于字符串集合中最短的字符串 if (res.length() < min_len) { res.push_back('a' + index); } } cur = cur->next[index]; } else { // 搜索到next不止有1个节点 cur = 0; } } } return res;}
scnt用于记录当前节点的子节点数,求解最长公共前缀时,子节点数超过1个,肯定就不是公共前缀了,注意这点。一些细节看代码注释即可。
0 0
- Trie树结构与实现
- 树结构--Trie树
- trie树结构
- Trie树 的理论与实现
- Trie树实现词频统计与查找
- Trie树的分析与实现
- Trie树,Java实现
- Trie树及其实现
- Trie树的实现
- Trie树的实现
- Trie树实现一
- Trie树实现二
- Trie树实现
- trie树Java实现
- Trie树 c++实现
- Trie树python实现
- Java实现Trie树
- Trie树实现
- 虚拟网桥和网卡的轮训工作
- CCF网络延时---求树中两个最远结点的距离
- oracle 12c 智能闪存缓存(smart flash cache)
- React Native中模拟器command+R刷新不了的问题
- 设计模式之--单例模式
- Trie树结构与实现
- Linux下运行程序时找不到链接库的解决办法
- JAVA-反射-getGenericSuperclass
- ReactJS分析之入口函数render
- Java基础之线程安全基本数据类型
- android系统裁剪方法
- 面试谈薪这些套路一定要懂,不然有你悔的!
- 基于 Quartz 开发企业级任务调度应用
- String方法