前缀树

#include <iostream>
#include <vector>
#include <stack>
#include <unordered_map>
using namespace std;

struct Node{
    int pass;
    int end;
    unordered_map<char, Node*> nexts;
    explicit Node():pass(0), end(0){}
};

class TireTree{
private:
    Node *head;
    stack<Node *> s;//用于删除
public:
    TireTree(){
        head = new Node();
    }
    void insert(const string &word){
        if(word.empty()){
            return;
        }
        Node *node = head;
        node->pass++;
        for(auto &it:word){
            //如果下面的节点里没找到
            if(node->nexts.find(it) == node->nexts.end()){
                //构建一个节点并插入到nexts中
                node->nexts[it] = new Node();
            }
            node = node->nexts[it];
            node->pass++;
        }
        node->end++;
    }
    void delectWord(const string &word){
        if(search(word) != 0) {
            auto node = head;
            for(auto &it:word){
                if(--node->pass == 0){
                    delectTree(node, word[0], node->nexts[word[0]]);
                    return;
                }
                node = node->nexts[it];
            }
            node->end--;
        }
    }
    //递归删除节点
    void delectTree(Node *father, char c, Node *node){
        if(node->nexts.empty()){
            father->nexts.erase(c);
            delete(node);
            return;
        }
        for(auto &it:node->nexts){
            delectTree(node, it.first, it.second);
        }
    }
    //判断这个单词加入过几次
    int search(const string &word){
        if(word.empty()) return 0;
        auto node = head;
        for(auto &it:word){
            if(node->nexts.find(it) == node->nexts.end()){
                return 0;
            }
            node = node->nexts[it];
        }
        return node->end;
    }
    //判断有几个是以pre做前缀的
    int preFixSearch(const string &pre){
        if(pre.empty()) return 0;
        auto node = head;
        for(auto &it:pre){
            if(node->nexts.find(it) == node->nexts.end()){
                return 0;
            }
            node = node->nexts[it];
        }
        return node->pass;
    }
};

int main() {
    vector<string> arr = {"abc", "abb", "bac","cdf", "abc", "aef"};
    auto tree = new TireTree();
    for(auto &it:arr){
        tree->insert(it);
    }
    cout<<tree->search("abc")<<endl;
    tree->delectWord("abc");
    cout<<tree->search("abc")<<endl;
    tree->delectWord("abc");
    cout<<tree->search("abc")<<endl;
    return 0;
}
posted @   蘑菇王国大聪明  阅读(32)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示