zoukankan      html  css  js  c++  java
  • Trie树之C-实现


    title: Trie树之C++实现
    comments: true
    date: 2016-10-02 16:59:54
    categories: 算法
    tags:

    • Trie树

    前言

    之前写了一篇偏向于理解Trie的文章-Trie树理解

    和前面那篇文章不同的是,这一篇文章记录着Trie树的C++实现

    介绍

    看一下代码的结构

    其中:

    • TrieNode : 树的结点,树
    • Client : 客户端(操作树)
    • main : 主函数

    Code

    TrieNode

    TrieNode.hpp

    //
    //  TreeNode.hpp
    //  Trie
    //
    //  Created by staff on 16/9/29.
    //  Copyright © 2016年 staff. All rights reserved.
    //
    
    #ifndef TreeNode_hpp
    #define TreeNode_hpp
    
    #include <stdio.h>
    #include <iostream>
    #include <map>
    #include <vector>
    #include <stack>
    using namespace std;
    
    #define MAX_CHARS 26
    
    class TreeNode {
    public:
        TreeNode();
        ~TreeNode();
        
        void setEnd(bool);
        bool getEnd();
        
        void setFreq(int);
        int getFreq();
        
        void setNChar(char);
        char getNChar();
        
        void setID(int);
        int getID();
    
        void setStr(string);
        string getStr();
        
        vector<TreeNode *> Childs;
        
    private:
        bool End;
        int Freq;
        char NChar;
        int Id;
        string str;
    };
    
    
    class Tree {
    public:
        Tree();
        ~Tree();
        
        void addTrieNode(string word, int id);
        void deleteTrieNode();
        map<int, string> searchTrie(string word);
        void upateTree(string word, int id);
        int getWordFreq(string word);
        
    private:
        TreeNode * root;
        void addTrieNode(TreeNode * node, string word, int id);
        void deleteTrieNode(TreeNode * root);
        map<int, string> searchTrie(TreeNode * root, string word);
        int getPrefixCount(TreeNode * root, string word);
        void upateTree(TreeNode * root, string word, int id);
        int getWordFreq(TreeNode * root, string word);
    };
    
    #endif /* TreeNode_hpp */
    
    

    TreeNode.cpp

    //
    //  TreeNode.cpp
    //  Trie
    //
    //  Created by staff on 16/9/29.
    //  Copyright © 2016年 staff. All rights reserved.
    //
    
    #include "TreeNode.hpp"
    
    TreeNode::TreeNode() : End(false), Freq(0), NChar(' '), str("") {
        for (int i = 0; i < MAX_CHARS; ++i) {
            this->Childs.push_back(nullptr);
        }
    }
    
    TreeNode::~TreeNode() {
        for (auto itr = this->Childs.begin(); itr != this->Childs.end(); itr++) {
            delete *itr;
            *itr = nullptr;
        }
        this->Childs.clear();
    }
    
    void TreeNode::setEnd(bool value) {
        this->End = value;
    }
    
    bool TreeNode::getEnd() {
        return this->End;
    }
    
    void TreeNode::setFreq(int value) {
        this->Freq = value;
    }
    
    int TreeNode::getFreq() {
        return this->Freq;
    }
    
    void TreeNode::setNChar(char value) {
        this->NChar = value;
    }
    
    char TreeNode::getNChar() {
        return this->NChar;
    }
    
    void TreeNode::setID(int value) {
        this->Id = value;
    }
    
    int TreeNode::getID() {
        return this->Id;
    }
    
    void TreeNode::setStr(string value) {
        this->str = value;
    }
    
    string TreeNode::getStr() {
        return this->str;
    }
    
    Tree::Tree() {
        this->root = new TreeNode();
    }
    
    Tree::~Tree() {
        
    }
    
    void Tree::addTrieNode(TreeNode * root, string word, int id) {
        if (word.size() == 0) {
            return ;
        }
    
        TreeNode * pNode = root;
        for (int i = 0; i < word.size(); ++i) {
            int idx = word[i] - 'a';
            if (pNode->Childs[idx] == nullptr) {
                pNode->Childs[idx] = new TreeNode();
            }
            pNode->Childs[idx]->setNChar(word[i]);
            pNode->Childs[idx]->setStr(pNode->getStr() + pNode->Childs[idx]->getNChar());
            pNode = pNode->Childs[idx];
        }
        
        pNode->setID(id);
        pNode->setFreq(pNode->getFreq()+1);
        pNode->setEnd(true);
    }
    
    void Tree::deleteTrieNode(TreeNode * root) {
        TreeNode * node = root;
        for (int i = 0; i < MAX_CHARS; ++i) {
            if (node->Childs[i]) {
                deleteTrieNode(node->Childs[i]);
            }
        }
        
        delete(node);
        node = nullptr;
    }
    
    map<int, string> Tree::searchTrie(TreeNode * root, string word) {
        if (word.size() == 0) {
            return {};
        }
        
        map<int, string> result;
        TreeNode * pNode = root;
        int i = 0;
        
        for (; i < word.size(); ++i) {
            int idx = word[i] - 'a';
            
            if (pNode->Childs[idx] == nullptr) {
                break;
            }
            
            pNode = pNode->Childs[idx];
        }
        
        if (i != word.size()) {
            cout << "not exist!" << endl;
            return {};
        }
        else {
            result.insert(make_pair(pNode->getID(), pNode->getStr()));
            stack<TreeNode *> stack;
            stack.push(pNode);
            
            while (!stack.empty()) {
                TreeNode * node = stack.top();
                stack.pop();
                
                for (int j = 0; j < MAX_CHARS; ++j) {
                    if (node->Childs[j]) {
                        if (node->Childs[j]->getEnd()) {
                            result.insert(make_pair(node->Childs[j]->getID(), node->Childs[j]->getStr()));
                        }
                        else {
                            stack.push(node->Childs[j]);
                        }
                    }
                }
            }
            return result;
        }
    
    }
    
    /**
     *  词频统计,出现字符串的个数
     *
     *  @param root <#root description#>
     *  @param word <#word description#>
     *
     *  @return <#return value description#>
     */
    int Tree::getWordFreq(TreeNode * root, string word) {
        TreeNode * pNode = root;
        
        int i = 0;
        for (; i < word.size(); ++i) {
            int idx = word[i] - 'a';
            
            if (pNode->Childs[idx] == nullptr) {
                return 0;
            }
            
            pNode = pNode->Childs[idx];
        }
        
        return pNode->getFreq();
    }
    
    void Tree::upateTree(TreeNode * root, string word, int id) {
        deleteTrieNode(root);
        addTrieNode(root, word, id);
    }
    
    void Tree::addTrieNode(string word, int id) {
        this->addTrieNode(this->root, word, id);
    }
    
    void Tree::deleteTrieNode() {
        this->deleteTrieNode(this->root);
    }
    
    map<int, string> Tree::searchTrie(string word) {
        return this->searchTrie(root, word);
    }
    
    int Tree::getWordFreq(string word) {
        return this->getWordFreq(this->root, word);
    }
    
    void Tree::upateTree(string word, int id) {
        this->upateTree(this->root, word, id);
    }
    
    

    Client

    Client.hpp

    //
    //  Client.hpp
    //  Trie
    //
    //  Created by staff on 16/9/29.
    //  Copyright © 2016年 staff. All rights reserved.
    //
    
    #ifndef Client_hpp
    #define Client_hpp
    
    #include <stdio.h>
    #include <iomanip>
    #include <fstream>
    #include <string>
    #include <algorithm>
    #include <map>
    #include "TreeNode.hpp"
    using namespace std;
    
    class Client {
    public:
        Client();
        ~Client();
        void test();
    
    private:
        Tree *tree;
    };
    
    #endif /* Client_hpp */
    
    

    Client.cpp

    //
    //  Client.cpp
    //  Trie
    //
    //  Created by staff on 16/9/29.
    //  Copyright © 2016年 staff. All rights reserved.
    //
    
    #include "Client.hpp"
    
    Client::Client() {
        this->tree = new Tree();
    }
    
    Client::~Client() {
        
    }
    
    void Client::test() {
        
        ifstream infile;
        infile.open("/Users/George/Desktop/out.txt");
        string message;
        char buf[1024];
        
        if (infile.is_open()) {
            while (infile.good() && !infile.eof()) {
                memset(buf, 0, 1024);
                infile.getline(buf, 1024);
                message = buf;
                
                size_t size = message.length();
                size_t space = message.find_first_of(' ');
                
                int id = atoi(message.substr(0, space).c_str());
                string word = message.substr(space+1, size-1);
                word.erase(word.end()-1);
                
                transform(word.begin(), word.end(), word.begin(), ::tolower);
                
                this->tree->addTrieNode(word, id);
            }
            
            char input[20];
            printf("please input
    ");
            scanf("%s", input);
            
            int content_count = this->tree->getWordFreq(input);
            printf("content count : %d
    ", content_count);
            
            map<int, string> ids = this->tree->searchTrie(input);
            
            int prefix_count = (int)ids.size();
            printf("prefix count : %d
    
    ", prefix_count);
            
            for (auto id : ids) {
                printf("%d:%s
    ", id.first, id.second.c_str());
            }
            
        }
        else {
            printf("无法读取文件
    ");
        }
        
        infile.close();
    }
    

    main

    //
    //  main.cpp
    //  Trie
    //
    //  Created by staff on 16/9/28.
    //  Copyright © 2016年 staff. All rights reserved.
    //
    
    #include <stdio.h>
    #include "Client.hpp"
    
    int main(int argc, const char * argv[]) {
        // insert code here...
        Client * client = new Client();
        client->test();
        
        return 0;
    }
    
    

    结果

  • 相关阅读:
    VBScript学习笔记
    C#调用C++库知识点
    .Net面试经验,从北京到杭州
    杭州.Net 相关大公司,希望对大家有帮助
    一起学习《C#高级编程》3--运算符重载
    一起学习《C#高级编程》2--比较对象的相等性
    一起学习《C#高级编程》1--类型的安全性
    博客园的第一天
    基于SpringCloud+Kubernetes 微服务的容器化持续交付实战
    第一节:Docker学习 — 安装
  • 原文地址:https://www.cnblogs.com/George1994/p/6399869.html
Copyright © 2011-2022 走看看