trie树(前缀树)

前缀树

  • 1. 前缀树的的介绍
  • 2.前缀树的实现
    • 2.1插入功能
    • 2.2删除功能
    • 2.3查找前缀和查找单词功能
    • 2.4 哈希表版本

1. 前缀树的的介绍

在计算机科学中,trie,又称前缀树或字典树,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。

2.前缀树的实现

如何实现一颗前缀树呢?这里有两种实现的方法,对应了不同的情况。

我们首先来定义一下前缀树的节点,我们让每一个根节点有两个值,一个为pass,一个为end,pass表示经过这个节点的次数,end表示走到叶子节点的次数(也就是这个单词出现的次数)。

我们先看看这棵树的结构。比如我们插入字符串{“aa”,“aaa”,“bba”,“ssba”},我们看看这颗树的结构。

在这里插入图片描述

现在我们模拟这个过程来写代码
先来定义好节点

struct TreeNode // 创建结点
{TreeNode *next[26];int end;int pass;TreeNode() // 初始化结点{end = 0;path = 0;for(int i=0;i<26;i++)next[i]=NULL;}
};

下面我们实现树的部分,我们就储存一个头节点和所需要的接口

class Trie
{
private:TreeNode* root;
public:Trie(){root = new TreeNode;}void insert_Node(string word); // 插入void Delete_Node(string word); // 删除int  search(string word); // 查找int prefixNumber(string word);//查找有多少以word作为前缀的单词
};

2.1插入功能

void Trie::insert_Node(string wrod)
{if (wrod == "") return;int idx = 0;TreeNode* node = root;root->pass++;for (int i = 0; i < wrod.size(); i++){idx = wrod[i] - 'a';if (node->next[idx]==nullptr)node->next[idx] = new TreeNode;node = node->next[idx];node->pass++;}node->end++;
}

2.2删除功能

//这个函数java的可以不用写,因为Java有JVM垃圾回收机制。
void Delete(TreeNode* node)
{if (node == NULL)return;for (int num = 0; num < 26; num++){if (node->next[num]){Delete(node->next[num]);}}delete(node);node=NULL;
}void Trie::Delete_Node(string word)
{if (!search(word))return;int index = 0;TreeNode* node = root;node->pass--;for (int i = 0; i < word.size(); i++){index = word[i] - 'a';if (--node->next[index]->pass == 0){// Java的直接将 node。next[index] = NULL  即可Delete(node->next[index]);node->next[index] = NULL;return;}node = node->next[index];}node->end--;
}

2.3查找前缀和查找单词功能

int Trie::prefixNumber(string word)
{if (word == "") return 0;int idx = 0;TreeNode* node = root;for (int i = 0; i < word.size(); i++){idx = word[i] - 'a';if (node->next[idx] == nullptr) return 0;node = node->next[idx];}return node->pass;
}
int Trie::search(string word)
{if (word == "") return 0;int idx = 0;TreeNode* node = root;for(int i=0;i<word.size();i++){ idx = word[i] - 'a';if (node->next[idx] == nullptr) return 0;node = node->next[idx];}return node->end;
}

2.4 哈希表版本

如何单词不只有26个小写字母,我们该如何去实现呢,我们可以通过哈希表去进行映射来实现。
只需要以ASIII作为key,代码稍微改动一下就可以了。

#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
using namespace std;struct TreeNode
{int pass;int end;unordered_map<int, TreeNode*> next;TreeNode(){pass = 0;end = 0;}};class Trie
{
private:TreeNode* root;
public:Trie(){root = new TreeNode;}void insert_Node(string word); // 插入void Delete_Node(string word); // 删除int  search(string word); // 查找int prefixNumber(string word);//查找有多少以word作为前缀的单词
};void Trie::insert_Node(string wrod)
{if (wrod == "") return;int idx = 0;TreeNode* node = root;root->pass++;for (int i = 0; i < wrod.size(); i++){idx = (int)wrod[i];if (!node->next.count(idx)){node->next[idx] = new TreeNode;}node = node->next[idx];node->pass++;}node->end++;
}int Trie::search(string word)
{if (word == "") return 0;int idx = 0;TreeNode* node = root;for(int i=0;i<word.size();i++){ idx = (int)word[i];if (!node->next.count(idx)) return 0;node = node->next[idx];}return node->end;
}
//这个函数java的可以不用写,因为Java有JVM垃圾回收机制。
void Delete(TreeNode* node)
{if (node == NULL)return;for (int num = 0; num < 26; num++){if (node->next[num]){Delete(node->next[num]);}}delete(node);node = NULL;
}void Trie::Delete_Node(string word)
{if (!search(word))return;int index = 0;TreeNode* node = root;node->pass--;for (int i = 0; i < word.size(); i++){index = (int)word[i];if (--node->next[index]->pass == 0){// Java的直接将 node。next[index] = NULL  即可Delete(node->next[index]);node->next[index] = NULL;return;}node = node->next[index];}node->end--;
}int Trie::prefixNumber(string word)
{if (word == "") return 0;int idx = 0;TreeNode* node = root;for (int i = 0; i < word.size(); i++){idx = (int)word[i];if (!node->next.count(idx)) return 0;node = node->next[idx];}return node->pass;
}int main()
{Trie tr;tr.insert_Node("aad");tr.insert_Node("jjafp");tr.insert_Node("jjdafp");tr.insert_Node("jjdafp");tr.insert_Node("jjafp");tr.insert_Node("jjdap");cout << tr.search("jjdafp") << endl;cout << tr.prefixNumber("j") << endl;return 0;
}

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

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

相关文章

MarkDown实用技巧:MarkDown中如何实现换行?

MarkDown实用技巧&#xff1a;MarkDown中如何实现换行&#xff1f; &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &#x1f448; 希望…

计讯物联5G RedCap网关TG463化繁为简,推动5G赋能千行百业

5G RedCap&#xff0c;全称为Reduced Capability&#xff0c;即在5G的基础上&#xff0c;对部分功能进行化繁为简后形成的新技术标准&#xff0c;故又称轻量化5G。作为高性价比下的精简技术&#xff0c;5G RedCap技术具备成本低、低功耗、兼顾5G等特点&#xff0c;能够在确保应…

【Android安全】Windows 环境下载 AOSP 源码

准备环境 安装 git 安装 Python 硬盘剩余容量最好大于 800G 打开 Git Bash&#xff0c;用 git 克隆源代码仓库 git clone https://android.googlesource.com/platform/manifest.git //没有梯子使用清华源 git clone https://aosp.tuna.tsinghua.edu.cn/platform/manifest.git这…

代码随想录算法训练营第36天 | 738.单调递增的数字 ,968.监控二叉树

贪心算法章节理论基础&#xff1a; https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 738.单调递增的数字 题目链接&#xff1a;https://leetcode.cn/problems/monotone-increasing-digits/ 思路&#xff1a; …

论文精读--VAE

自编码器(Auto-Encoder)是学一个特征能够代表输入的图像 而VAE则为数据的隐变量加上先验——将隐变量限制为一个标准正态分布&#xff0c;也就是学一个具有代表性的分布 Abstract How can we perform efficient inference and learning in directed probabilistic models, in…

git忽略某些文件(夹)更改方法

概述 在项目中,常有需要忽略的文件、文件夹提交到代码仓库中,在此做个笔录。 一、在项目根目录内新建文本文件,并重命名为.gitignore,该文件语法如下 # 以#开始的行,被视为注释. # 忽略掉所有文件名是 a.txt的文件. a.txt # 忽略所有生成的 java文件, *.java # a.j…

Time Travel

题目链接 解题思路 由于所有边集中的边加起来的总和至多为&#xff0c;无向图即&#xff0c;可以存下所以直接对所有边集中的边进行建边&#xff0c;同时对于每条边&#xff0c;记录其所在边集号对于每个边集&#xff0c;由大到小维护其能通过的时间点然后从1号跑最短路到当前…

高级语言期末2011级A卷(软件学院)

1.编写函数&#xff0c;判定正整数m和n&#xff08;均至少为2&#xff09;是否满足&#xff1a;数m为数n可分解的最小质因数&#xff08;数n可分解的最小质因数为整除n的最小质数&#xff09; 提示&#xff1a;判定m为质数且m是n的最小因数 #include <stdio.h> #include…

DiffiT | 英伟达提出用于图像生成的扩散ViT架构DiffiT,达成新SOTA!

本文首发于AIWalker&#xff0c;欢迎关注。 https://arxiv.org/abs/2312.02139 https://github.com/NVlabs/DiffiT 扩散模型以其强大的表达能力和高样本质量在许多领域得到了新的应用。对于样本生成&#xff0c;这些模型依赖于通过迭代去噪生成图像的去噪神经网络。然而&#…

坚持刷题|二叉树展开为链表

文章目录 题目考察点代码实现实现总结扩展问题用递归的方式实现在展开二叉树为链表的过程中&#xff0c;递归和迭代两种方法各有什么优缺点&#xff1f;可能的扩展问题 Hello&#xff0c;大家好&#xff0c;我是阿月。坚持刷题&#xff0c;老年痴呆追不上我&#xff0c;今天刷&…

LTD营销枢纽2023年度功能升级回顾

在过去的2023年&#xff0c;我们的团队致力于不断进步和创新。经过一年的不懈努力&#xff0c;我们共发布了50次的系统升级&#xff0c;引入了16种全新的解决方案与业务应用&#xff0c;并实施了1363项各类细致优化。 这些更新和改进不仅在我们的营销枢纽系统现有功能的基础上实…

35岁程序员,深入理解JVM的核心知识点

网络&#xff1a;分层模型、TCP、UDP、HTTP、HTTPS 分层模型 应用层&#xff1a;负责处理特定的应用程序细节&#xff0c;如 HTTP、FTP、DNS运输层&#xff1a;为两台主机提供端到端的基础通信&#xff0c;如 TCP、UDP网络层&#xff1a;控制分组传输、路由选择等&#xff0c…

【大数据架构(1)】Lambda Architecture – Realtime Data Processing 论文重点翻译

文章目录 1. INTRODUCTION2. LAMBDA ARCHITECTUREA) BATCH LAYERB) SPEED LAYERC) SERVICE LAYER 3. LIMITATIONS OF THE TRADITIONAL LAMBDAARCHITECTURE4. A PROPOSED SOLUTION1. 架构说明2. 前后架构改进对比 1. INTRODUCTION Lambda架构背后的需求是由于虽然MR能够处理大数…

SpringBoot+PDF.js实现按需分片加载预览(包含可运行示例源码)

SpringBootPDF.js实现按需分片加载预览 前言分片加载的效果前端项目前端项目结构前端核心代码前端项目运行 后端项目后端项目结构后端核心代码后端项目运行 项目运行效果首次访问分片加载 项目源码 前言 本文的解决方案旨在解决大体积PDF在线浏览加载缓慢、影响用户体验的难题…

Fabric V2.5 通用溯源系统——区块链部分设计

本节对Fabric V2.5 通用溯源系统的区块链部分做一个简单的介绍,包括目录结构、文件作用、设计思路。此节内容免费发布在TrueTechLabs Fabric学习交流QQ群。 购买专栏前请认真阅读:《Fabric项目学习笔记》专栏介绍 TrueTechLabs Fabric学习交流QQ群: 一、区块链部分文件目录简…

代码库管理工具Git介绍

阅读本文同时请参阅-----免费的Git图形界面工具sourceTree介绍 Git是一个分布式版本控制系统&#xff0c;它可以帮助开发者跟踪和管理代码历史。Git的命令行工具是使用Git的核心方式&#xff0c;虽然它可能看起来有些复杂&#xff0c;但是一旦掌握了基本命令&#xff0c;你…

【C++私房菜】序列式容器的迭代器失效问题

目录 一、list的迭代器失效 二、vector的迭代器失效 1、空间缩小操作 2、空间扩大操作 三、总结 在C中&#xff0c;当对容器进行插入或删除操作时&#xff0c;可能会导致迭代器失效的问题。所谓迭代器失效指的是&#xff0c;原先指向容器中某个元素的迭代器&#xff0c;在…

Retrofit核心原理

Retrofit是一个类型安全的HTTP客户端库&#xff0c;广泛用于Android和Java应用中&#xff0c;用于简化网络请求和响应的处理。本文将深入探讨Retrofit的核心原理&#xff0c;帮助开发者理解其背后的工作机制。 Retrofit简介 Retrofit是Square公司开发的一个开源库&#xff0c…

MWC 2024丨美格智能推出5G RedCap系列FWA解决方案,开启5G轻量化新天地

2月27日&#xff0c;在MWC 2024世界移动通信大会上&#xff0c;美格智能正式推出5G RedCap系列FWA解决方案。此系列解决方案具有低功耗、低成本等优势&#xff0c;可以显著降低5G应用复杂度&#xff0c;快速实现5G网络接入&#xff0c;提升FWA部署的经济效益。 RedCap技术带来了…

pclpy Ransac平面分割算法输出的索引从点云中提取点云的子集

pclpy Ransac平面分割算法输出的索引从点云中提取点云的子集 一、算法原理二、代码三、结果1.sor统计滤波2.Ransac内点分割平面3.Ransac外点分割平面 四、相关数据 一、算法原理 1、Ransac介绍 RANSAC(RAndom SAmple Consensus,随机采样一致)算法是从一组含有“外点”(outlier…