版权声明:长风原创 https://blog.csdn.net/u012846486/article/details/80546643
字典树又称为前缀树或Trie树,是处理字符串的常见数据结构。本实现提供了以下五个功能。
1.bool Insert(const string& word) 添加word,可重复添加
2.bool Delete(const string& word) 删除word,如果word添加过多次,仅删除一个
3.bool Search(const string& word) 查询word是否在字典树中
4.int PrefixNumber(const string& pre) 返回以pre为前缀的单词数量
5.int Size() 返回字典树中存储的单词个数
#include <iostream>
#include <cstdio>
#include <string>
#include <map>
using namespace std;
struct TrieTree
{
private:
struct TrieNode
{
int path;
int last;
map<char, TrieNode*> next;
TrieNode()
: path(0),
last(0)
{
}
~TrieNode()
{
for (auto& v : next) {
delete v.second;
v.second = NULL;
}
next.clear();
}
};
public:
bool Insert(const string& word)
{
if (word.empty())
return false;
TrieNode *current_node = &root;
for (size_t i = 0; i <= word.size(); ++i) {
++current_node->path;
char key = word[i];
if (key == '\0') {
++current_node->last;
return true;
}
auto& next_node = current_node->next[key];
if (next_node == NULL) {
next_node = new TrieNode;
}
current_node = next_node;
}
return false;
}
int Size()
{
return root.path;
}
bool Search(const string& word)
{
if (word.empty())
return false;
TrieNode *current_node = &root;
for (size_t i = 0; i < word.size(); ++i) {
char key = word[i];
TrieNode *next_node = NULL;
auto it = current_node->next.find(key);
if (it == current_node->next.end())
return false;
next_node = it->second;
current_node = next_node;
}
return current_node->last != 0;
}
bool Delete(const string& word)
{
if (!Search(word))
return false;
TrieNode *current_node = &root;
for (size_t i = 0; i <= word.size(); ++i) {
--current_node->path;
char key = word[i];
if (key == '\0') {
--current_node->last;
return true;
}
current_node = current_node->next[key];
}
return true;
}
int PrefixNumber(const string& word)
{
if (word.empty())
return 0;
TrieNode *current_node = &root;
for (size_t i = 0; i <= word.size(); ++i) {
char key = word[i];
if (key == '\0') {
return current_node->path;
}
TrieNode *next_node = NULL;
auto it = current_node->next.find(key);
if (it == current_node->next.end())
return 0;
next_node = it->second;
current_node = next_node;
}
}
private:
TrieNode root;
};
int main(int argc, char const *argv[])
{
TrieTree trie_tree;
trie_tree.Insert("ab");
trie_tree.Insert("abc");
trie_tree.Insert("abcd");
trie_tree.Insert("abcde");
printf("trie_tree.Size:%d\n", trie_tree.Size());
printf("trie_tree.Search(abcd):%d\n", trie_tree.Search("abcd"));
printf("trie_tree.Search(abcf):%d\n", trie_tree.Search("abcf"));
printf("trie_tree.Delete(abcf):%d\n", trie_tree.Delete("abcf"));
printf("trie_tree.Delete(abcd):%d\n", trie_tree.Delete("abcd"));
printf("trie_tree.Size:%d\n", trie_tree.Size());
printf("trie_tree.PrefixNumber(ab):%d\n", trie_tree.PrefixNumber("ab"));
printf("trie_tree.PrefixNumber(abc):%d\n", trie_tree.PrefixNumber("abc"));
printf("trie_tree.PrefixNumber(abcf):%d\n", trie_tree.PrefixNumber("abcf"));
return 0;
}
运行调试:
g++ -std=c++11 test.cpp && valgrind ./a.out