1. 应用场景
- 字符串检索,查询
- 词频统计
- 字符串排序,插入的时候就是有顺序的,所以先序遍历,就得到字典树的排序。
- 前缀匹配
抄自<算法竞赛 入门进阶>,挺好的一本书。
2. c++实现
struct Trie{
Trie* next[26];
int num;
Trie(){
for (int i = 0; i < 26; ++i) {
next[i]= nullptr;
}
num=0;
}
};
Trie root;
void Insert(char str[]){
Trie *p = &root;
for (int i = 0; str[i]; ++i) {
if (p->next[str[i]-'a']== nullptr)
p->next[str[i]-'a'] = new Trie;
p = p->next[str[i]-'a'];
p->num++;
}
}
int Find(char str[]){
Trie *p = &root;
for (int i = 0; str[i]; ++i) {
if (p->next[str[i]-'a']== nullptr)
return 0;
p = p->next[str[i]-'a'];
}
return p->num;
}
书里面的struct可以用c++11 来简化一下
struct Trie{
Trie* next[26]={nullptr};
int num=0;
};
对应的hdu1251 模板题。
当然那个struct 里面还可以加一些东西,然后修改的insert和find的时候相应的改一下。比如lc的208.
工程实现稍微有点弱,因为root 是全局变量。
3. 更好的工程实现 lc208
class Trie {
private:
// Trie *root;
Trie* next[26]={nullptr};
bool is_string = false;
// Trie* next[26];
// int p;
public:
/** Initialize your data structure here. */
Trie() {
}
/** Inserts a word into the trie. */
void insert(string word) {
// 定义临时变量root
Trie* root = this;
for (int i = 0; i < word.length(); ++i) {
if (root->next[word[i]-'a']== nullptr){
root->next[word[i]-'a']= new Trie();
}
root = root->next[word[i]-'a'] ;
}
root->is_string=true;
}
/** Returns if the word is in the trie. */
bool search(string word) {
Trie* root = this;
for (auto w:word) {
if(root->next[w-'a']== nullptr)
return false;
root = root->next[w - 'a'];
}
return root->is_string;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
bool startsWith(string prefix) {
Trie* root = this;
for (auto p:prefix){
if (root->next[p-'a']== nullptr){
return false;
}
root = root->next[p-'a'];
}
return true;
}
};
很好的工程板子。