字典树

1. 应用场景

  1. 字符串检索,查询
  2. 词频统计
  3. 字符串排序,插入的时候就是有顺序的,所以先序遍历,就得到字典树的排序。
  4. 前缀匹配

抄自<算法竞赛 入门进阶>,挺好的一本书。

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;
    }
};

很好的工程板子。

原文地址:https://www.cnblogs.com/gqdw/p/14389418.html