tinystl实现(第二十四步:字典树实现)

39 篇文章 4 订阅
28 篇文章 37 订阅

经过长时间的学习终于可以开始tinystl的仿(chao)写工作了,本文参考了这位大神的github,坦白讲我只是补充了注释,因为tinystl的代码真的非常经典而我又没什么这种大型项目的经验,所以只能这样做,不过相信能够有助于大家的学习
#强烈建议按顺序阅读本专栏
.h文件

#pragma once
#ifndef _TRIE_TREE_H_
#define _TRIE_TREE_H_

#include "String.h"
#include "Vector.h"

#include <utility>
#include <memory>
#include <map>
#include <iostream>

namespace mySTL {
	class trie_tree {
	private:
		struct trie_node {
			char data;
			bool is_a_word;
			std::map<char, std::unique_ptr<trie_node>> map_childs;
			trie_node() :data('\0'), is_a_word(false) {}
			trie_node(char ch, bool is) :data(ch), is_a_word(is) {}
		};
		typedef std::unique_ptr<trie_node> node_ptr;
	public:
		typedef string value_type;
		typedef size_t size_type;
	private:
		trie_node *root_;
		size_type size_;
	public:
		trie_tree();
		~trie_tree();
		trie_tree(const trie_tree&) = delete;
		trie_tree& operator = (const trie_tree&) = delete;

		bool empty()const;
		size_type size()const;

		vector<string> 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:
		node_ptr make_node(char ch, bool is_a_word);
		inline trie_node* get_root()const { return root_; }
		void _get_word_by_prefix(const string& prefix, const node_ptr& up, const string& real_prefix, vector<string>& words)const;
		void __get_word_by_prefix(const node_ptr& up, string& word, const string& prefix, vector<string>& words)const;
		void _print_tree(std::ostream& os, const node_ptr& up, string word)const;
		bool _insert(const string& word, const node_ptr& up);
		bool _is_existed(const string& word, const node_ptr& up)const;
	};// end of trie_tree
}

#endif

cpp文件

#include"../TrieTree.h"
namespace mySTL {
	trie_tree::trie_tree() :root_(new trie_node), size_(0) {}
	trie_tree::~trie_tree() {
		if (root_) {
			root_->map_childs.clear();
			delete root_;
		}
	}
	bool trie_tree::empty()const {
		return size() == 0;
	}
	trie_tree::size_type trie_tree::size()const {
		return size_;
	}
	//
	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]);//此处返回一个map
		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, const node_ptr& up)const {
		if (word.size() == 1)
			return up->is_a_word;
		char ch = word[1];
		auto res = up->map_childs.find(ch);
		if (res == up->map_childs.end())//not found
			return false;
		else
			return _is_existed(word.substr(1), res->second);//每次截取掉头一个
	}
	trie_tree::node_ptr trie_tree::make_node(char ch, bool is_a_word) {
		return std::make_unique<trie_node>(ch, is_a_word);
	}
	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()) {
			return _insert(word.substr(1), res->second);
		}
		else {
			auto is_a_word = (word.size() == 1 ? true : false);//是否结尾
			auto node = make_node(ch, is_a_word);
			root->map_childs[ch] = std::move(node);
			return _insert(word.substr(1), root->map_childs[ch]);
		}
	}
	bool trie_tree::_insert(const string& word, const node_ptr& up) {
		if (word.empty()) {
			++size_;
			up->is_a_word = true;
			return true;
		}
		char ch = word[0];
		auto res = up->map_childs.find(ch);
		if (res != up->map_childs.end()) {
			return _insert(word.substr(1), res->second);
		}
		else {
			auto is_a_word = (word.size() == 1 ? true : false);
			auto node = make_node(ch, is_a_word);
			up->map_childs[ch] = std::move(node);
			return _insert(word.substr(1), up->map_childs[ch]);
		}
	}
	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, const node_ptr& up, string word)const {
		word += up->data;
		if (up->is_a_word)
			os << word << std::endl;
		for (auto cit = up->map_childs.cbegin(); cit != up->map_childs.cend(); ++cit) {
			_print_tree(os, cit->second, word);
		}
	}
	vector<string> trie_tree::get_word_by_prefix(const string& prefix)const {
		vector<string> 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, const node_ptr& up,
		const string& real_prefix, vector<string>& words)const {
		if (prefix.size() == 1) {
			if (up->is_a_word)
				words.push_back(real_prefix);
			for (auto cit = up->map_childs.cbegin(); cit != up->map_childs.cend(); ++cit) {
				__get_word_by_prefix(cit->second, string(), real_prefix, words);
			}
		}
		else {
			char ch = prefix[1];
			auto res = up->map_childs.find(ch);
			if (res != up->map_childs.end()) {
				_get_word_by_prefix(prefix.substr(1), res->second, real_prefix, words);
			}
		}
	}
	//有后缀的部分
	void trie_tree::__get_word_by_prefix(const node_ptr& up, string& word,
		const string& prefix, vector<string>& words)const {
		word += up->data;
		if (up->is_a_word)
			words.push_back(prefix + word);
		for (auto cit = up->map_childs.cbegin(); cit != up->map_childs.cend(); ++cit) {
			__get_word_by_prefix(cit->second, string(word), prefix, words);
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值