前缀树Trie

简介: 前缀树Trie

Trie树,即字典树,是一种树形结构,是一种哈希树的变种。主要用来统计和排序大量的字符串,所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较。

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

这里提供前缀树的封装接口:增加,删除,查询有无指定字符串及模糊查询。

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int SIZE  = 26;
struct TrieNode {
    bool isEnd = false;
    int count = 0;
    string word = "";
    struct TrieNode* children[SIZE];
};
class Trie {
public:
    Trie();
    ~Trie();
    void destroyNode(TrieNode *& node);// only pass TrieNode* cannot make node = nullptr
    void addWord(const std::string& word);
    void removeWord(const std::string& word);
    bool hasWord(const std::string& word) const;
    void getWords(TrieNode *node, vector<std::string> &vecStr) const;
    std::vector<std::string> emumerateWords(const std::string& prefix) const;
private:
    TrieNode *root = nullptr;
    TrieNode *createTrieNode();
};
Trie::Trie(){
    root = new TrieNode();
}
Trie::~Trie(){
    destroyNode(root);
}
void Trie::destroyNode(TrieNode *& node){
    if(node == nullptr)
        return;
    for(int i = 0;i < SIZE; i++){
        destroyNode(node->children[i]);
    }
    delete node;
    node = nullptr;// if use TrieNode* this code cannot work well
}
TrieNode* Trie::createTrieNode(){
    TrieNode *pNode = new TrieNode();
    for(int i=0; i < SIZE; ++i)
        pNode->children[i] = nullptr;
    return pNode;
}
void Trie::addWord(const std::string& word){
    TrieNode *node = root;
    int index = 0;
    for(auto ch : word){
        index = ch - 'a'; 
        if(node->children[index] == nullptr){
            node->children[index] = createTrieNode();
        }
        node = node->children[index];
        node->count ++;
    }
    node->isEnd = true;
    node->word = word;
}
void Trie::removeWord(const std::string& word){
    if(!hasWord(word)){
        std::cout << word <<" not in data set, please check" << std::endl;
        return;
    }
    TrieNode *node = root;
    int index = 0;
    for(auto ch : word){
        index = ch - 'a';
        node = node->children[index];
        if(--node->count == 0){
            destroyNode(node);
            return;
        }
    }
    node->isEnd = false;
}
bool Trie::hasWord(const std::string& word) const{
    TrieNode *node = root;
    int index = 0;
    for(auto ch : word){
        index = ch - 'a'; 
        if(node->children[index] != nullptr)
            node = node->children[index];
        else
            return false;
    }
    return node->isEnd; 
}
void Trie::getWords(TrieNode* node, vector<string> &vecStr) const{
   if(node == nullptr) 
       return ;
   if(node->isEnd)
       vecStr.push_back(node->word);
   for(int i = 0; i < SIZE; i++){
       getWords(node->children[i],vecStr);
   }
}
std::vector<std::string> Trie::emumerateWords(const std::string& prefix) const{
    TrieNode *node = root;
    std::vector<std::string> res;
    int index = 0;
    for(auto ch : prefix){
        index = ch - 'a'; 
        if(node->children[index] != nullptr)
            node = node->children[index];
        else
            return res;
    }
    getWords(node,res);
    return res;
}

其中最重要,也是最容易发生错误的接口是删除操作,如操作不当容易内存泄漏。查找了很多文章,析构函数均写得有问题,这里提供完整的功能接口。笔试题可能会遇到。

目录
打赏
0
0
0
0
3
分享
相关文章
告别繁琐查找!Python高级数据结构Trie树与Suffix Tree,让数据处理更轻松!
【7月更文挑战第19天】Python的Trie树优化字符串搜索,利用前缀减少无效操作,提升效率;Suffix Tree则高效处理后缀问题,尤其适用于文本搜索与生物信息学。虽构建复杂,但能加速后缀查询。掌握这两种数据结构,能有效应对大规模数据挑战,简化处理流程,提升开发效率。
206 0
Python进阶必备:字典树Trie与后缀树Suffix Array,效率提升的神器!
在Python编程中,掌握高效的数据结构对于提升程序性能至关重要。本文将深入探讨两种强大的字符串处理数据结构——字典树(Trie)与后缀数组(Suffix Array)。字典树,又称前缀树,适用于自动补全和拼写检查等功能。例如,在文本编辑器中实现自动补全时,字典树能够即时提供单词补全选项。后缀数组则用于存储字符串的所有后缀并按字典序排序,结合最长公共前缀(LCP)数组,可以高效解决许多字符串问题,如查找最长重复子串等。通过实际案例,我们将展示这两种数据结构的强大功能,帮助你在Python编程中更进一步。
171 2
深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索树或图的算法。
深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索树或图的算法。
关于k8s 集群版本升级的一些笔记(不能跨次要版本升级)
分享一些 K8s 集群版本升级的笔记 博文为根据官方文档的版本升级记录 理解不足小伙伴帮忙指正
1008 0
docker pull出现错误或速度慢解决办法
在使用 Docker 时遇到拉取镜像速度慢的问题,可以使用国内的镜像源可以提高下载速度。
3391 0
Hyper V上网实战:多虚拟机网络环境配置
在Hyper-V环境中配置多虚拟机网络以实现上网功能,需完成以下步骤:1. 确认Hyper-V安装与物理网络连接正常;2. 配置虚拟交换机(外部、内部或专用)以支持不同网络需求;3. 设置虚拟机网络适配器并关联对应虚拟交换机;4. 验证虚拟机网络连接状态;5. 根据场景需求优化多虚拟机网络环境。此外,还需注意网络隔离、性能监控及数据备份等事项,确保网络安全稳定运行。
C++ operator关键字的使用(重载运算符、仿函数、类型转换操作符)
C++ operator关键字的使用(重载运算符、仿函数、类型转换操作符)
317 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等