From 0dc655accd18916043805999692d94b05cff8887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=99=93=E8=88=AA?= <1210603696@qq.com> Date: Sat, 14 Feb 2015 01:00:01 +0800 Subject: [PATCH] add trie_tree --- TinySTL/Detail/TireTree.cpp | 119 ++++++++++++++++++++++++++++++++ TinySTL/TinySTL.vcxproj | 2 + TinySTL/TinySTL.vcxproj.filters | 6 ++ TinySTL/TrieTree.h | 42 +++++++++++ 4 files changed, 169 insertions(+) create mode 100644 TinySTL/Detail/TireTree.cpp create mode 100644 TinySTL/TrieTree.h diff --git a/TinySTL/Detail/TireTree.cpp b/TinySTL/Detail/TireTree.cpp new file mode 100644 index 0000000..de0c7f6 --- /dev/null +++ b/TinySTL/Detail/TireTree.cpp @@ -0,0 +1,119 @@ +#include "../TrieTree.h" + +namespace TinySTL{ + trie_tree::trie_tree(){ + data = new trie_node; + data->is_a_word = false; + data->map_childs.clear(); + } + trie_tree::~trie_tree(){ + if (data){ + data->map_childs.clear(); + delete data; + } + } + bool trie_tree::is_existed(const string& word)const{ + if (word.empty()) + return false; + auto root = get_root(); + auto res = root->map_childs.find(word[0]); + if (res == root->map_childs.end())//not found + return false; + else + return _is_existed(word, res->second); + } + bool trie_tree::_is_existed(const string& word, std::shared_ptr sp)const{ + if (word.size() == 1) + return sp->is_a_word; + char ch = word[1]; + auto res = sp->map_childs.find(ch); + if (res == sp->map_childs.end())//not found + return false; + else + return _is_existed(word.substr(1), res->second); + } + bool trie_tree::insert(const string& word){ + if (is_existed(word)) + return true; + if (word.empty()) + return false; + char ch = word[0]; + auto root = get_root(); + auto res = root->map_childs.find(ch); + if (res != root->map_childs.end()){ + string tmp_word(word.substr(1)); + return _insert(tmp_word, res->second); + }else{ + auto new_sp = std::make_shared(); + new_sp->data = ch; + new_sp->is_a_word = (word.size() == 1 ? true : false); + root->map_childs[ch] = new_sp; + return _insert(word.substr(1), new_sp); + } + } + bool trie_tree::_insert(const string& word, std::shared_ptr sp){ + if (word.empty()){ + sp->is_a_word = true; + return true; + } + char ch = word[0]; + auto res = sp->map_childs.find(ch); + if (res != sp->map_childs.end()){ + return _insert(word.substr(1), res->second); + }else{ + auto new_sp = std::make_shared(); + new_sp->data = ch; + new_sp->is_a_word = (word.size() == 1 ? true : false); + sp->map_childs[ch] = new_sp; + return _insert(word.substr(1), new_sp); + } + } + void trie_tree::print_tree(std::ostream& os)const{ + auto root = get_root(); + if (root == NULL) + os << "the trie_tree is empty!" << std::endl; + for (auto cit = root->map_childs.cbegin(); cit != root->map_childs.cend(); ++cit) + _print_tree(os, cit->second, string()); + } + void trie_tree::_print_tree(std::ostream& os, std::shared_ptr sp, string word)const{ + word += sp->data; + if (sp->is_a_word) + os << word << std::endl; + for (auto cit = sp->map_childs.cbegin(); cit != sp->map_childs.cend(); ++cit){ + _print_tree(os, cit->second, word); + } + } + vector trie_tree::get_word_by_prefix(const string& prefix)const{ + vector words; + auto root = get_root(); + if (root == NULL || prefix.size() == 0) + return words; + char ch = prefix[0]; + auto res = root->map_childs.find(ch); + if (res != root->map_childs.end()) + _get_word_by_prefix(prefix, res->second, prefix, words); + return words; + } + void trie_tree::_get_word_by_prefix(const string& prefix, std::shared_ptr sp, + const string& real_prefix, vector& words)const{ + if (prefix.size() == 1){ + for (auto cit = sp->map_childs.cbegin(); cit != sp->map_childs.cend(); ++cit){ + __get_word_by_prefix(cit->second, string(), real_prefix, words); + } + }else{ + char ch = prefix[1]; + auto res = sp->map_childs.find(ch); + if (res != sp->map_childs.end()){ + _get_word_by_prefix(prefix.substr(1), res->second, real_prefix, words); + } + } + } + void trie_tree::__get_word_by_prefix(std::shared_ptr sp, string& word, const string& prefix, vector& words)const{ + word += sp->data; + if (sp->is_a_word) + words.push_back(prefix + word); + for (auto cit = sp->map_childs.cbegin(); cit != sp->map_childs.cend(); ++cit){ + __get_word_by_prefix(cit->second, string(word), prefix, words); + } + } +} \ No newline at end of file diff --git a/TinySTL/TinySTL.vcxproj b/TinySTL/TinySTL.vcxproj index 86b7fee..ea04359 100644 --- a/TinySTL/TinySTL.vcxproj +++ b/TinySTL/TinySTL.vcxproj @@ -82,6 +82,7 @@ + @@ -147,6 +148,7 @@ + diff --git a/TinySTL/TinySTL.vcxproj.filters b/TinySTL/TinySTL.vcxproj.filters index 788a71f..88293bc 100644 --- a/TinySTL/TinySTL.vcxproj.filters +++ b/TinySTL/TinySTL.vcxproj.filters @@ -87,6 +87,9 @@ Test + + Detail + @@ -239,6 +242,9 @@ Test + + 头文件 + diff --git a/TinySTL/TrieTree.h b/TinySTL/TrieTree.h new file mode 100644 index 0000000..b6afbb0 --- /dev/null +++ b/TinySTL/TrieTree.h @@ -0,0 +1,42 @@ +#ifndef _TRIE_TREE_H_ +#define _TRIE_TREE_H_ + +#include "String.h" +#include "Vector.h" + +#include +#include +#include +#include + +namespace TinySTL{ + class trie_tree{ + private: + struct trie_node{ + char data; + bool is_a_word; + std::map> map_childs; + }; + private: + trie_node *data; + public: + trie_tree(); + ~trie_tree(); + trie_tree(const trie_tree&) = delete; + trie_tree& operator = (const trie_tree&) = delete; + + vector get_word_by_prefix(const string& prefix)const; + void print_tree(std::ostream& os = std::cout)const; + bool insert(const string& word); + bool is_existed(const string& word)const; + private: + inline trie_node* get_root()const{ return data; } + void _get_word_by_prefix(const string& prefix, std::shared_ptr sp, const string& real_prefix, vector& words)const; + void __get_word_by_prefix(std::shared_ptr sp, string& word, const string& prefix, vector& words)const; + void _print_tree(std::ostream& os, std::shared_ptr sp, string word)const; + bool _insert(const string& word, std::shared_ptr sp); + bool _is_existed(const string& word, std::shared_ptr sp)const; + };// end of trie_tree +} + +#endif \ No newline at end of file -- GitLab