Trie.h 檔案
#ifndef _TRIE_H
#define _TRIE_H
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
inline int sub_size(int level)
{
return level > 5 ? 1 : 256 / (level * level * level);
}
struct search_tree
{
search_tree(int level)
{
int len = sub_size(level);
word = false;
sub_tree = new search_tree *[len];
next = NULL;
for (int i = 0; i < len; i++)
sub_tree[i] = NULL;
}
char cchar;
bool word;
search_tree **sub_tree;
search_tree *next;
};
class Trie
{
public:
Trie()
{
for (int i = 0; i < 256; i++)
T[i] = NULL;
}
~Trie()
{
for (int i = 0; i < 256; i++)
search_tree_delete(T[i], 1);
}
int add(char *str);
int prefix_in_tree(char *str);
private:
void search_tree_delete(search_tree *s_tree, int level);
void search_tree_add(search_tree *&s_tree, char *str, int level);
int prefix_in_tree(search_tree *s_tree, char *str, int level);
unsigned int hash(unsigned char cchar, int len);
search_tree *T[256];
};
#endif
trie.cpp
#include "trie.h"
using namespace std;
unsigned int Trie::hash(unsigned char cchar, int len)
{
return cchar % len;
}
int Trie::add(char *str)
{
int hash_code = hash((unsigned char)(*str), 256);
search_tree_add(T[hash_code], str, 1);
return 1;
}
int Trie::prefix_in_tree(char *str)
{
return prefix_in_tree(*(T + (unsigned char)(*str)), str, 1);
}
void Trie::search_tree_add(search_tree *&s_tree, char *str, int level)
{
search_tree *cur = NULL;
if (s_tree == NULL)
{
s_tree = new search_tree(level + 1);
s_tree->cchar = *str;
cur = s_tree;
}
else
{
if (s_tree->cchar != *str)
{
s_tree->next = new search_tree(level + 1);
s_tree->next->cchar = *str;
cur = s_tree->next;
}
else
cur = s_tree;
}
if (*(str + 1) == '/0')
{
cur->word = true;
return;
}
int hash_code = hash(*(str + 1), sub_size(level + 1));
search_tree_add(cur->sub_tree[hash_code], str + 1, level + 1);
return;
}
int Trie::prefix_in_tree(search_tree *s_tree, char *str, int level)
{
if (s_tree == NULL || *str == '/0')
return 0;
int hash_code;
for (search_tree *cur = s_tree; cur != NULL; cur = cur->next)
{
if (cur->cchar == *str)
{
if (cur->word)
return level;
hash_code = hash(*(str + 1), sub_size(level + 1));
return prefix_in_tree(cur->sub_tree[hash_code], str + 1, level + 1);
}
}
return 0;
}
void Trie::search_tree_delete(search_tree *s_tree, int level)
{
if (s_tree == NULL)
return;
search_tree_delete(s_tree->next, level);
int len = sub_size(level + 1);
for (int i = 0; i < len; i++)
{
search_tree_delete(s_tree->sub_tree[i], level + 1);
}
delete s_tree;
}