#include<iostream>
#include<string>
#include<set>
using namespace std;
//实现前缀树(字典树)
class TrieNode {
public:
int end;//表示最终以这个字符串结束的字符串有多少个
int p;//表示此点经过了几次
TrieNode** arr;
int size;//表示字符数组中有几个有效值,主要是为了解决leetcode上的题目
TrieNode() {
end = 0;
p = 0;
arr = new TrieNode * [26]();
size = 0;
}
};
class TrieTree {
private:
TrieNode* root;
public:
TrieTree() {
root = new TrieNode;
}
void insert(string s) {
if (s.size() == 0) {
return;
}
TrieNode* node = root;
node->p++;
int index;
for (int i = 0; i < s.size(); i++) {
index = s[i] - 'a';
if (node->arr[index] == nullptr) {
node->arr[index] = new TrieNode;
node->size++;
}
node = node->arr[index];
node->p++;
}
node->end++;
}
int search(string s) {
//s在前缀树中出现过几次
if (s.size() == 0) {
return 0;
}
int index;
TrieNode* node = root;
for (int i = 0; i < s.size(); i++) {
index = s[i] - 'a';
if (node->arr[index] == nullptr) {
return 0;
}
node = node->arr[index];
}
return node->end;
}
int prefixNumber(string s) {
//以s为前缀的字符串有多少个
if (s.size() == 0) {
return 0;
}
int index;
TrieNode* node = root;
for (int i = 0; i < s.size(); i++) {
index = s[i] - 'a';
if (node->arr[index] == nullptr) {
return 0;
}
node = node->arr[index];
}
return node->p;
}
void Delete(string s) {
if (search(s) == 0) {
return;
}
set<TrieNode*> dset;
int deleteindex = -1, index;
TrieNode* deleteNode = nullptr;
TrieNode* node = root;
node->p--;
for (int i = 0; i < s.size(); i++) {
index = s[i] - 'a';
if (--node->arr[index]->p == 0) {
deleteNode = deleteNode == nullptr ? node : deleteNode;
deleteindex = deleteindex == -1 ? index : deleteindex;
dset.insert(node->arr[index]);
}
node = node->arr[index];
}
node->end--;
if (dset.size() != 0) {
deleteNode->arr[deleteindex] = nullptr;
for (TrieNode* n : dset) {
delete n;
}
}
}
};
经典的前缀树中的结点是没有数值的
这里为了解决leetcode的第14题,特意加了个size
14. 最长公共前缀 - 力扣(LeetCode)https://leetcode.cn/problems/longest-common-prefix/