#include <stdlib.h>
#include <time.h>
#include <iostream>
#include <vector>
#include <string>
#include <thread>
#define SAFE_DEL(p) do { if (nullptr != p) { delete p; p = nullptr; }} while (0)
enum class TrieNodeType {
UNCOMPLETED,
COMPLETED
};
struct trie_node {
static const size_t MAX_NODE_NUM = 256;
TrieNodeType type = TrieNodeType::UNCOMPLETED;
trie_node *links[MAX_NODE_NUM] = { nullptr };
};
class trie_tree {
public:
trie_tree() = default;
trie_tree(const trie_tree &) = delete;
trie_tree & operator = (const trie_tree &) = delete;
virtual ~trie_tree() {
destory(root_);
}
public:
bool init() {
try {
root_ = new trie_node;
}
catch (...) {
return false;
}
init_succ = true;
return true;
}
bool insert(const char *word) {
char ch = 0;
trie_node *ptr = nullptr;
if (false == init_succ) {
return false;
}
auto cur_node_ptr = root_;
for (int i = 0;word[i];i++) {
ch = word[i];
if (false == charater_is_valid(ch)) {
return false;
}
auto &link = cur_node_ptr->links[ch];
if (nullptr == link) {
ptr = create_node();
link = ptr;
}
cur_node_ptr = link;
}
if (TrieNodeType::COMPLETED == cur_node_ptr->type) {
std::cerr << "word:" << word << " reapted." << std::endl;
return false;
}
cur_node_ptr->type = TrieNodeType::COMPLETED;
return true;
}
bool find(const char *word) {
char ch = 0;
trie_node *ptr = nullptr;
if (false == init_succ) {
return false;
}
auto cur_node_ptr = root_;
for (int i = 0;word[i];i++) {
ch = word[i];
if (false == charater_is_valid(ch)) {
return false;
}
auto &link = cur_node_ptr->links[ch];
if (nullptr == link) {
return false;
}
cur_node_ptr = link;
}
return TrieNodeType::COMPLETED == cur_node_ptr->type;
}
bool find(const char *prefix_word, std::vector<std::string>&words) {
char ch = 0;
trie_node *ptr = nullptr;
if (false == init_succ) {
return false;
}
auto cur_node_ptr = root_;
std::string str;
for (int i = 0;prefix_word[i];i++) {
ch = prefix_word[i];
if (false == charater_is_valid(ch)) {
return false;
}
auto &link = cur_node_ptr->links[ch];
if (nullptr == link) {
return false;
}
str += ch;
cur_node_ptr = link;
}
find_all_words(cur_node_ptr, str, words);
return true;
}
private:
inline trie_node *create_node() {
trie_node *ptr = nullptr;
try {
ptr = new trie_node;
}
catch (std::exception &e) {
std::cerr << e.what() << std::endl;
::exit(-1);
}
return ptr;
}
bool charater_is_valid(char ch) {
return (ch >= 0 && ch < trie_node::MAX_NODE_NUM);
}
void find_all_words(const trie_node *ptr, std::string &str, std::vector<std::string>&words) {
if (nullptr == ptr) {
return;
}
char ch = 0;
for (size_t index = 0;index < trie_node::MAX_NODE_NUM;index++) {
auto &link = ptr->links[index];
if (nullptr == link) {
continue;
}
ch = index;
str += ch;
find_all_words(link, str, words);
}
if (TrieNodeType::COMPLETED == ptr->type) {
words.emplace_back(str);
}
str.erase(end(str) - 1);
}
void destory(trie_node *&ptr) {
if (nullptr == ptr) {
return;
}
for (size_t index = 0;index < trie_node::MAX_NODE_NUM;index++) {
destory(ptr->links[index]);
}
SAFE_DEL(ptr);
}
private:
trie_node *root_ = nullptr;
bool init_succ = false;
};
void thread_fun() {
trie_tree trieTree;
if (false == trieTree.init()) {
std::cerr << "trie tree init failed." << std::endl;
return;
}
char buf[64] = "";
for (int i = 0;i < 10000;i++) {
snprintf(buf, sizeof(buf), "%ld", time(0));
trieTree.insert(buf);
}
}
int main() {
/*std::vector<std::thread>threads;
for (int i = 0;i < 10;i++) {
threads.emplace_back(std::thread(thread_fun));
}
for (auto &th : threads) {
th.join();
}*/
trie_tree trieTree;
if (false == trieTree.init()) {
std::cerr << "trie tree init failed." << std::endl;
return -1;
}
trieTree.insert("a");
trieTree.insert("ab");
trieTree.insert("abhj");
trieTree.insert("abhjklop");
trieTree.insert("basabhjklop");
trieTree.insert("asabhjklop12");
trieTree.insert("abc");
std::cout << trieTree.find("a") << std::endl;
std::cout << trieTree.find("ab") << std::endl;
std::cout << trieTree.find("abc") << std::endl;
const char *prefix_word = "a";
std::vector<std::string>words;
std::cout << trieTree.find(prefix_word, words) << std::endl;
for (auto &word : words) {
std::cout << "word = " << word << std::endl;
}

return 0;
}