1. 简介
前缀树是一种数据结构,常用来字符串前缀搜索。
2. 实现
包含的操作主要是:
- 加入串
- 搜索串
代码实现,直接用leetcode_208的题解咯。
2.1 实现一:链表
- 代码
class Trie {
public:
Trie():isEnd(false){
for ( int i = 0; i < 26;++i)
child[i] = nullptr;
}
~Trie() {
for ( int i = 0; i < 26; ++i ) {
if (child[i]) {
delete child[i];
child[i] = nullptr;
}
}
}
void insert(string word) {
Trie *cur = this;
int sz = word.size();
for (int i = 0; i < sz; ++i) {
int idx = word[i] - 'a';
if ( cur->child[idx] == nullptr) {
Trie *nxt = new Trie();
cur->child[idx] = nxt;
}
cur = cur->child[idx];
}
cur->isEnd = true;
}
bool search(string word) {
Trie *cur = this;
int sz = word.size();
for (int i = 0; i < sz; ++i) {
int idx = word[i] - 'a';
if (cur->child[idx] == nullptr)
return false;
cur = cur->child[idx];
}
return cur->isEnd;
}
bool startsWith(string prefix) {
int sz = prefix.size();
Trie *cur = this;
for (int i = 0; i < sz; ++i ) {
int idx = prefix[i] - 'a';
if (cur->child[idx] == nullptr)
return false;
cur = cur->child[idx];
}
return true;
}
private:
bool isEnd;
Trie *child[26];
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
2.2 实现二:数组模拟链表
class Trie {
static constexpr int NO_POS = -1;
static constexpr int MAXM = 5e4;
public:
Trie():cnt(0){
for (int i = 0;i < MAXM;++i) {
auto tmp_ptr = shared_ptr<array<int,26>>(new array<int,26>());
tmp_ptr->fill(NO_POS);
trie.push_back(tmp_ptr);
}
exist.reset(new vector<int>(MAXM, 0));
}
~Trie() {
}
void insert(string word) {
int sz = word.size();
int p = 0;
for (auto c:word) {
int idx = c - 'a';
if (NO_POS == trie[p]->at(idx)){
trie[p]->at(idx) = ++cnt;
}
p = trie[p]->at(idx);
}
(*exist)[p] = 1;
}
bool search(string word) {
int p = 0;
int sz = word.size();
for (auto c:word) {
int idx = c - 'a';
if (trie[p]->at(idx) == NO_POS) {
return false;
}
p = trie[p]->at(idx);
}
return (*exist)[p];
}
bool startsWith(string prefix) {
int p = 0;
int sz = prefix.size();
for (auto c:prefix) {
int idx = c - 'a';
if (trie[p]->at(idx) == NO_POS) {
return false;
}
p = trie[p]->at(idx);
}
return true;
}
private:
vector<shared_ptr<array<int,26>> > trie;
shared_ptr<vector<int>> exist;
int cnt;
};
/**
* Your Trie object will be instantiated and called as such:
* Trie* obj = new Trie();
* obj->insert(word);
* bool param_2 = obj->search(word);
* bool param_3 = obj->startsWith(prefix);
*/
UPD
- 2024/3/22
加入数组模拟链表实现的前缀树,并使用智能指针