前缀树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;
}

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

相关文章
|
SQL 关系型数据库 MySQL
探索Gorm - Golang流行的数据库ORM框架
探索Gorm - Golang流行的数据库ORM框架
|
机器学习/深度学习 算法 安全
密码学系列之五:MD5、SHA1——一文搞懂哈希函数
密码学系列之五:MD5、SHA1——一文搞懂哈希函数
8740 0
|
12月前
|
存储 算法 搜索推荐
Python进阶必备:字典树Trie与后缀树Suffix Array,效率提升的神器!
在Python编程中,掌握高效的数据结构对于提升程序性能至关重要。本文将深入探讨两种强大的字符串处理数据结构——字典树(Trie)与后缀数组(Suffix Array)。字典树,又称前缀树,适用于自动补全和拼写检查等功能。例如,在文本编辑器中实现自动补全时,字典树能够即时提供单词补全选项。后缀数组则用于存储字符串的所有后缀并按字典序排序,结合最长公共前缀(LCP)数组,可以高效解决许多字符串问题,如查找最长重复子串等。通过实际案例,我们将展示这两种数据结构的强大功能,帮助你在Python编程中更进一步。
206 2
|
6月前
|
监控 安全 网络协议
Hyper V上网实战:多虚拟机网络环境配置
在Hyper-V环境中配置多虚拟机网络以实现上网功能,需完成以下步骤:1. 确认Hyper-V安装与物理网络连接正常;2. 配置虚拟交换机(外部、内部或专用)以支持不同网络需求;3. 设置虚拟机网络适配器并关联对应虚拟交换机;4. 验证虚拟机网络连接状态;5. 根据场景需求优化多虚拟机网络环境。此外,还需注意网络隔离、性能监控及数据备份等事项,确保网络安全稳定运行。
2024年 | 12月云大使推广奖励规则
【近期云大使规则升级】①上线企业云大使提现功能。②增加返利订单类目。③优化推广奖励限制。④提升首购后订单返利比例。⑤新增沉睡用户返利 。⑥推荐企业认证新用户首购最高奖励45%。
|
存储 数据处理 开发者
告别繁琐查找!Python高级数据结构Trie树与Suffix Tree,让数据处理更轻松!
【7月更文挑战第19天】Python的Trie树优化字符串搜索,利用前缀减少无效操作,提升效率;Suffix Tree则高效处理后缀问题,尤其适用于文本搜索与生物信息学。虽构建复杂,但能加速后缀查询。掌握这两种数据结构,能有效应对大规模数据挑战,简化处理流程,提升开发效率。
259 0
|
人工智能 算法 Java
深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索树或图的算法。
深度优先搜索(Depth-First Search,DFS)是一种用于遍历或搜索树或图的算法。
|
存储 算法 Java
【DFS(深度优先搜索)详解】看这一篇就够啦
本文介绍了深度优先搜索(DFS)算法及其应用。DFS从某个顶点出发,深入探索图的每条路径,直到无法前进为止,然后回溯。文章详细解释了DFS的基本思想,并通过示例图展示了其执行过程。此外,文中还探讨了三种枚举方式:指数型枚举、排列型枚举和组合型枚举,并提供了具体的代码实现。最后,文章通过几道练习题帮助读者更好地理解和应用DFS算法。
8581 19
【DFS(深度优先搜索)详解】看这一篇就够啦
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
详谈什么是自然语言处理(NLP),特点以及使用场景场景(一)
详谈什么是自然语言处理(NLP),特点以及使用场景场景(一)
414 0
|
分布式计算 Hadoop 大数据
MapReduce 案例之数据去重
MapReduce 案例之数据去重
407 0