字典树,前缀树,某方面比哈希表还厉害的玩意

字典树详解(Trie树,前缀树) 用伪代码手把手构建字典树 阅读详情

前缀树

Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
它有3个基本性质:

  1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
  2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符都不相同。

https://blog.youkuaiyun.com/v_july_v/article/details/6897097
https://www.cnblogs.com/cherish_yimi/archive/2009/10/12/1581666.html

Trie.h

#ifndef TRIE_H
#define TRIE_H
#include <vector>
#include <string>

class Trie
{
public:
    Trie();
    ~Trie();

    /**
     * @brief 检测树中是否存在word这个单词
     * @param word   需要检测的字符串
     * @return 存在返回true, 失败返回false
     */
    bool hasWord(const std::string &word);

    /**
     * @brief 检测树中是否存在单词以prifix为前缀开头
     * @param prefix   需要检测的字符串
     * @return 存在返回true, 失败返回false
     */
    bool startsWith(std::string prefix);

    /**
     * @brief 在前缀树中增加一个单词
     * @param word  需要增加的单词
     */
    void addWord(const std::string &word);

    /**
     * @brief 在前缀树中删除一个单词
     * @param word  需要删除的单词
     */
    void removeWord(const std::string &word);

    /**
     * @brief 返回具有给定前缀的单词列表
     * @param prefix 匹配所需的单词
     */
    std::vector<std::string> enumerateWords(const std::string &prefix) const;

    /**
     * @brief 删除前缀树中的所有单词
     */
    void clearNode();

private:
    // 字符哈希表
    std::vector<Trie *> children;
    // 是否有单词结尾
    bool isEnd;

private:
    /**
     * @brief 查找给定单词字符序列在树中的最后一个节点
     * @param prefix 查找所需的单词
     * @return 如果单词的序列在树中存在则返回prefix单词序列中的最后一个字母的节点,
     *         如果不存在返回nullptr
     */
    Trie *searchPrefix(std::string prefix)const;

    void scanningTrie(Trie const *node, std::vector<std::string> &result, std::string word) const;
};

#endif // TRIE_H

Trie.cpp

#include "Trie.h"
using namespace std;
#define LETTER_SIZE 26

Trie::Trie() :
    children(LETTER_SIZE),	//每个节点相当于是一个哈希表,里面放着下一个节点的指针
    isEnd(false)			//是否有单词在这里进行结尾
{
}

Trie *Trie::searchPrefix(string prefix)const  //搜索是否有这个单词的结尾
{
    Trie const *node = this;
    for (char ch : prefix) {
        ch -= 'a';
        if (node->children[ch] == nullptr) {
            return nullptr;
        }
        node = node->children[ch];
    }

    return const_cast<Trie *>(node);
}

void Trie::addWord(const std::string &word)
{
    Trie *node = this;
    for (char ch : word) {
        ch -= 'a';
        if (node->children[ch] == nullptr) {
            node->children[ch] = new Trie();		//如果没有这个节点就生成这个节点
        }
        node = node->children[ch];
    }
    node->isEnd = true;
}

bool Trie::hasWord(const std::string &word)
{
    const Trie *node = this->searchPrefix(word);
    return node != nullptr && node->isEnd;
}

bool Trie::startsWith(string prefix)
{
    return this->searchPrefix(prefix) != nullptr;
}

void Trie::removeWord(const string &word)
{
    if (word.size() == 0) {
        this->isEnd = false;
        return;
    }

    int i;
    Trie *cur = this, *node = this; /*记录从哪里开始删除*/
    char record = word[0] - 'a';
    for (char ch : word) {
        ch -= 'a';
        if (cur->children[ch] == nullptr) {
            return; /*没有该单词直接返回*/
        }

        for (i = 0; i < LETTER_SIZE; i++) {
            if (ch != i && cur->children[i] != nullptr || cur->isEnd == true) {
                node = cur;    /*更新需要删除的位置*/
                record = ch;
                break;
            }
        }
        cur = cur->children[ch];
    }

    cur->isEnd = false;
    for (i = 0; i < LETTER_SIZE; i++) {  /*检测是否有更长的单词*/
        if (cur->children[i] != nullptr)
            break;
    }

    if (LETTER_SIZE == i && node != nullptr) {
        delete node->children[record];
        node->children[record] = nullptr;
    }
}

vector<string> Trie::enumerateWords(const string &prefix)const
{
    vector<string> result;

    Trie const *node = searchPrefix(prefix);
    if (node == nullptr) {
        return result;
    }
    scanningTrie(node, result, prefix);
    return result;
}

void Trie::scanningTrie(Trie const *node, std::vector<string> &result, string word) const
{
    if (nullptr == node) {
        return;
    }

    for (size_t i = 0; i < node->children.size(); i++) {
        Trie *pNode = node->children[i];
        if (nullptr != pNode) {
            char c = 'a' + i;
            string temp(word);
            temp.push_back(c);
            if (true == pNode->isEnd) {
                result.push_back(temp);
            }

            scanningTrie(pNode, result, temp);
        }
    }
}

void Trie::clearNode()
{
    for (size_t i = 0; i < this->children.size(); i++) {
        Trie *pNode = this->children[i];
        if (nullptr != pNode) {
            delete pNode;
            children[i] = nullptr;
        }
    }

    this->isEnd = false;
}

Trie::~Trie()
{
    clearNode();
}

代码有问题的地方希望各位指出啊

字典树-大量字符串前缀及出现次数是否存在统计(Trie树-java)算法实现 前言        字典树又称单词查找树,它是一种树形结构,是一种哈希树的变种,典型应用是用于统计,保存大量的字符串(但不仅限于字符串),统计以是否有以某字符串最为前缀的字符串,有的话有多少,某字符串出现了多少次等,所以经常被搜索引擎系统用于文本词频统计。        它与字典很相似,当你要查一个单词是不是在字典树中,首先看单词的第一个字母是不是在字典的第一层,如果不在,说明字典树里没有该单 阅读详情

相关推荐

Trie(字典树、前缀树)详解与实现

Trie(字典树、前缀树)是一种专门为"字符串集合"设计的多叉树结构,通过共享公共前缀来加速插入、查询和前缀匹配等操作。它用空间换时间,在搜索框联想、词频统计、敏感词过滤等场景非常常见。

六六哥的博客 1176

前缀树..

这篇文文章给大家讲解前缀树的知识,前缀树是非常重要的,也是AC自动机的一个基础.希望能给大家带来新的收获.提升codeing能力。

欢迎来到我的博客,在这里我会用我的方式来讲解知识,请大家多多关照 737

C++高级数据结构算法 | Tire树(字典树、前缀树)

Trie树的基本概念与应用场景、 Trie树的结构定义、单词插入操作、单词查找操作、前缀查询、删除算法、销毁操作、 LeetCode 208 实现 Trie (前缀树) 题解

ZY-JIMMY 4478

字典树(前缀树)

Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种,典型应用是用于统计和排序大量相同的字符串,所以经常被搜索引擎系统用于文本词频统计。它的优点是: 利用字符串的公共前缀来减少查询时间,最大限度地减少无谓字符串的比较。有些参考书将堆直接定义为序列,但是,从逻辑结构上讲,还是将堆定义为完全二叉树更好。虽然堆的典型实现方法是数组,但从逻辑的角度上讲,堆实际上是一种树结构。Trie的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

m0_53157173的博客 1039

哈希表与字典树原理入门

数据结构中介绍hash表与trie树的原理,图文并茂,一看就懂

用SOLIDWORKS从零画一个履带机器人,手把手教你搞定底盘和传动

本文详细介绍了如何使用SOLIDWORKS从零开始设计履带式机器人,重点讲解底盘结构优化和传动系统设计的关键步骤。通过七个阶段的实战指南,包括前期规划、底盘建模、驱动系统装配、履带生成、动态模拟等,帮助工程师和爱好者掌握履带机器人的核心设计技巧,提升地形适应能力和动力效率。

weixin_30872499的博客 632

字典树

字典树,也称前缀树,是一种哈希树的变种。典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。主要思想是用时间来换空间。 上面这棵Trie树包含的字符串集合是{in, inn, int, tea, ten, to}。每个节点的编号是我们为了描述方便加上去的。树中的每一条边上都标识有一...

A_Pathfinder的博客 540

别再只盯着CXL协议了,聊聊CXL.mem里那个能动态调优内存性能的‘QoS遥测’到底怎么用

本文深入解析CXL.mem协议中的QoS遥测功能,探讨如何通过DevLoad指标动态调优内存性能。文章详细介绍了QoS遥测的核心机制、多QoS类别设备的实战配置,以及AI训练、金融交易和视频处理场景中的优化案例,帮助数据中心实现高效内存资源管理。

weixin_33725722的博客 436

基础数据结构(二):字典树、并查集、堆、哈希表、字符串的哈希方式、STL的常见容器及其接口

基础数据结构(二):字典树、并查集、堆、哈希表、字符串的哈希方式、STL的常见容器及其接口

CS_boy的博客 1223

VMware + ubuntu20.04 + qemu安装

遇到报错可参考:(从ubuntu裸系统开始安装)

NosONE 3230

PyMOL下载安装教程(附安装包)2025最新版(PyMOL 3.0.3)

本文详细介绍了Windows系统下PyMOL分子建模软件的安装教程。主要内容包括:提供安装包下载链接,强调需关闭杀毒软件;分步骤讲解管理员身份运行安装程序、接受协议、选择安装路径等安装流程;重点说明如何配置隐藏文件夹ProgramData中的许可证文件;最后提供基础使用技巧和常见问题解决方案。该教程适用于需要制作高质量分子结构图的科研人员和新手用户,帮助完成软件部署并顺利开展工作。

progalchemist的博客 3791

字典树简介、应用以及与哈希表的比较

题目要求:1、设计并实现N-array trie,包括初始化,查找,插入,删除等。 2、应用trie结构实现文本文档的索引化,首先扫描文本文档,然后利用trie结构记录单词行号,最后在trie上实现查询 3、用户的查询可以是针对一个单词,也可以是某些字母开头的。 我的思路:根据题目的要求,用字典树这一数据结构实现最为符合,下面介绍一下字典树: 字典树介绍:我们拿存储英文单词的字典树为例,从实质上来讲

liyongqi_的博客 2275

从零到一:用STM32 FOC算法驯服无刷电机的艺术

本文详细介绍了如何使用STM32和FOC算法实现无刷电机的高性能控制。从硬件搭建、参数识别到闭环调节,一步步解析FOC算法的核心原理与调优技巧,帮助开发者掌握电机控制的关键技术,实现从零到一的精准驯服。

kkk56的博客 917

字典树(Trie/前缀树)

Trie 字典树 前缀树

good good study, day day up! 7867

基于Python的信用卡欺诈检测机器学习案例报告

当今时代,在线支付已成为一种高效便捷的支付方式,我们可以突破时间和空间的限制,输入我们的信用卡各项信息就可以完成在线支付。但随之而来的是这种支付方式也具备一定的风险性,我们无法辨别对方是否是恶意套取我们资金的非法分子。当信用卡信息数据泄露导致金钱失窃并最终失去客户忠诚度和公司声誉时,组织、消费者、银行和商家都会面临风险。2017 年,未经授权的信用卡操作达到了惊人的 1670 万受害者。此外,据美国联邦贸易委员会 (FTC) 报告,2017 年信用卡欺诈索赔数量比上一年高出 40%。

weixin_45673389的博客 6691

智能织梦:基于Rokid AR眼镜的家庭情感记忆增强系统设计与实践

本文介绍了基于Rokid AR眼镜的'智能织梦'系统,通过增强现实技术捕捉和重现家庭情感记忆。系统利用多模态传感器和轻量级情感识别模型,自动记录家庭互动中的情感峰值时刻,并生成沉浸式记忆片段。测试数据显示,该系统显著提升了家庭情感互动的频率和质量,特别适用于多代同堂家庭和记忆唤醒场景。

sre5engineer的博客 536

C++前缀树 字典树 TrieTree的学习与模拟实现

前缀树 字典树 TrieTree的学习与模拟实现

wtl666_6的博客 7070

交流电路计算方法:复阻抗和相量法

一,复阻抗 电容电路,电压与电流的大小比值是XC=1/WC,相位上电流比电压超前90度 这样描述很麻烦,在复平面里,相位超前90度,可以用什么数学表示呢? 也就是说,一个相量,乘以j之后,大小没变化,相位变得超前90度了 同样的,大小不变,相位落后90度应该除以j 原来我们说电容电路,给个电压,算电流又要算XC,又要另外说相位超前90度,现在可以简单点 在这个计算式里,1/wc还是原来的容抗大...

theory and practice的博客 3万+

Trie树(字典树,前缀树,键树)分析详解

Trie树概述   Trie树,又称字典树、前缀树、单词查找树、键树,是一种多叉树形结构,是一种哈希树的变种。Trie这个术语来自于retrieval,发音为/tri:/ “tree”,也有人读为/traɪ/ “try”。Trie树典型应用是用于快速检索(最长前缀匹配),统计,排序和保存大量的字符串,所以经常被搜索引擎系统用于文本词频统计,搜索提示等场景。它的优点是最大限度地减少无谓的字符串比较,查

Hyman's Blog 2万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Trie(字典树/前缀树)

字典树/前缀树

weixin_45746505的博客 3548

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【数据结构】Trie字典树(前缀树)— 数组实现

字典树(Trie),又称前缀树或单词查找树,是一种树形数据结构。字典树的特点是每个节点代表一个字符,从根节点到叶子节点的路径表示一个完整的字符串(或单词)。字典树主要用于高效地存储和检索字符串集合。字典树的核心思想是通过共享字符前缀来减少存储空间和提高查询效率。例如,如果多个字符串共享相同的前缀(如 “cat” 和 “car” 共享 “ca”),那么在字典树中,这些前缀只会存储一次。假设插入的顺序为:“cat”,“dog”,“door”,“deer”,“pan”,“panda”。就会形成如下字典树。

2301_76606232的博客 1660

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

字典树(前缀树)

图文并茂,包你理解

weixin_64132124的博客 776

前缀树是什么 前缀树的使用场景

前缀树的概述 前缀树又名字典树,单词查找树,Trie树,是一种多路树形结构,是哈希树的变种,和hash效率有一拼,是一种用于快速检索的多叉树结构。 典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。 Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。 Trie树也有它的缺点,Trie树的内存消耗非常大。 性质:不同字符串的相同前缀只保存一份。 操作:查找

youif的博客 5730

C++图解前缀树(字典树)

今天看到了最长公共前缀树的时候就突然想到了前几个星期学的前缀树。所以打算来写写。 试想有这样一种场景,我们现在手里有10W个单词,并且里面有重复的单词,如果我们使用传统的遍历手法查找一个单词,那么可能没等查出来交卷铃声已经响了。 或许有人会说使用哈希表,但是存在重复的单词,这个效率还是欠缺了点。 所以就引入了今天的主角—字典树。 字典树又称之为前缀树,是一个哈希表的变种,优于哈希表的查找速度。但是他的空间复杂度是十分复杂的,所以是一种空间换时间的做法。 ...

强者之路 1294

前缀树(字典树)总结-java版

目录 前缀树的概述 前缀树的应用场景 前缀树的java实现 节点 前缀树(增加,查询字符串数量,查询前缀数量) 测试 与DFA查询敏感词的类似与不同 类似 不同 前缀树的概述 前缀树又名字典树,单词查找树,Trie树,是一种多路树形结构,是哈希树的变种,和hash效率有一拼,是一种用于快速检索的多叉树结构。 典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经...

今天吃了吗的博客 3081

前缀树(字典树)

前缀树设计

weixin_45746505的博客 1153
上一篇: inotif机制,监控文件系统变化
下一篇: Linux定时任务
Advsance
博客等级 码龄8年 37粉丝 72原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值