前言
传统的字典树只有26个路,只能实现小写字母a~z开头的单词查找,解决这一问题可以使用哈希表来存储。该代码纯自己手写,不保证完全正确,拿慎选。
编译器
Microsoft Visual Studio 2022
代码如下
#include <iostream>
#include <unordered_map>
class Node {
public:
int pass;
int end;
std::unordered_map<int, Node*> nexts;
public:
Node() {
pass = 0;
end = 0;
}
};
class TrieTree {//字典树类
private:
Node* root;
public:
TrieTree() {//构造函数
root = new Node();
}
void insertWord(const std::string& word) {//插入单词
if (word.empty()) {
std::cout << "NULL" << std::endl;
return;
}
Node* node = root;
node->pass++;
int index = 0;
for (int i = 0; i < word.size(); ++i) {
index = (int)word[i];
if (node->nexts.count(index) == 0) {
std::pair<int, Node*> temp;
temp.first = index;
temp.second = new Node();
node->nexts.insert(temp);
}
node = node->nexts.at(index);
node->pass++;
}
node->end++;
//std::cout << "Insert finished" << std::endl;//这里可以打印验证
}
int searchWord(const std::string& word) {//查找单词
if (word.empty()) {
std::cout << "NULL" << std::endl;
return 0;
}
Node* node = root;
int index = 0;
for (int i = 0; i < word.size(); ++i) {
index = (int)word[i];
if (node->nexts.count(index) == 0) {
return 0;
}
node = node->nexts.at(index);
}
return node->end;
}
int perfixNumber(const std::string& word) {//查找哪些单词有这个前缀
if (word.empty()) {
std::cout << "NULL" << std::endl;
return 0;
}
Node* node = root;
int index = 0;
for (int i = 0; i < word.size(); ++i) {
index = (int)word[i];
if (node->nexts.count(index) == 0) {
return 0;
}
node = node->nexts.at(index);
}
return node->pass;
}
void deleteWord(const std::string& word) {//删除单词
if (searchWord(word) != 0) {
Node* node = root;
int index = 0;
for (int i = 0; i < word.size(); ++i) {
index = (int)word[i];
if (--node->nexts.at(index)->pass == 0) {
destoryNode(node->nexts.at(index), word, i + 1);
node->nexts.at(index) = nullptr;
//std::cout << "delete finished by 1" << std::endl;//这里可以打印验证
return;
}
node = node->nexts.at(index);
}
node->end--;
//std::cout << "delete finished by 2" << std::endl;//这里可以打印验证
return;
} else {
std::cout << "Word in NULL!" << std::endl;
return;
}
}
private:
void destoryNode(Node* begin, const std::string& word, const int& pos) {//递归删除begin为始的节点
if (begin == nullptr || pos >= word.size()) {
return;
}
Node* next = begin->nexts.at((int)word[pos]);
destoryNode(next, word, pos + 1);
delete begin;
}
};
int main() {
TrieTree* trietree = new TrieTree();
std::cin.get();
return 0;
}
备注
代码只是经过了简单的数据测试,没有写对数器,可能存在错误,欢迎大家讨论。