字典树的实现

版权声明:长风原创 https://blog.csdn.net/u012846486/article/details/80546643

字典树又称为前缀树或Trie树,是处理字符串的常见数据结构。本实现提供了以下五个功能。
1.bool Insert(const string& word) 添加word,可重复添加
2.bool Delete(const string& word) 删除word,如果word添加过多次,仅删除一个
3.bool Search(const string& word) 查询word是否在字典树中
4.int PrefixNumber(const string& pre) 返回以pre为前缀的单词数量
5.int Size() 返回字典树中存储的单词个数

#include <iostream>
#include <cstdio>
#include <string>
#include <map>

using namespace std;

struct TrieTree
{
private:
    struct TrieNode
    {
        int path;
        int last;
        map<char, TrieNode*> next;

        TrieNode() 
          : path(0),
            last(0)
        {
        }

        ~TrieNode()
        {
            for (auto& v : next) {
                delete v.second;
                v.second = NULL;
            }
            next.clear();
        }
    };

public:
    bool Insert(const string& word)
    {
        if (word.empty())
            return false;

        TrieNode *current_node = &root;
        for (size_t i = 0; i <= word.size(); ++i) {
            ++current_node->path;

            char key = word[i];
            if (key == '\0') {
                ++current_node->last;
                return true;
            }

            auto& next_node = current_node->next[key];
            if (next_node == NULL) {
                next_node = new TrieNode;
            }

            current_node = next_node;
        }

        return false;
    }

    int Size()
    {
        return root.path;
    }

    bool Search(const string& word)
    {
        if (word.empty())
            return false;

        TrieNode *current_node = &root;
        for (size_t i = 0; i < word.size(); ++i) {
            char key = word[i];

            TrieNode *next_node = NULL;
            auto it = current_node->next.find(key);
            if (it == current_node->next.end())
                return false;
            next_node = it->second;

            current_node = next_node;
        }

        return current_node->last != 0;
    }

    bool Delete(const string& word)
    {
        if (!Search(word))
            return false;

        TrieNode *current_node = &root;
        for (size_t i = 0; i <= word.size(); ++i) {
            --current_node->path;
            char key = word[i];
            if (key == '\0') {
                --current_node->last;
                return true;
            }

            current_node = current_node->next[key];
        }

        return true;
    }

    int PrefixNumber(const string& word)
    {
        if (word.empty())
            return 0;

        TrieNode *current_node = &root;
        for (size_t i = 0; i <= word.size(); ++i) {
            char key = word[i];
            if (key == '\0') {
                return current_node->path;
            }

            TrieNode *next_node = NULL;
            auto it = current_node->next.find(key);
            if (it == current_node->next.end())
                return 0;
            next_node = it->second;

            current_node = next_node;
        }
    }

private:
    TrieNode root;
};

int main(int argc, char const *argv[])
{
    TrieTree trie_tree;

    trie_tree.Insert("ab");
    trie_tree.Insert("abc");
    trie_tree.Insert("abcd");
    trie_tree.Insert("abcde");
    printf("trie_tree.Size:%d\n", trie_tree.Size());
    printf("trie_tree.Search(abcd):%d\n", trie_tree.Search("abcd"));
    printf("trie_tree.Search(abcf):%d\n", trie_tree.Search("abcf"));
    printf("trie_tree.Delete(abcf):%d\n", trie_tree.Delete("abcf"));
    printf("trie_tree.Delete(abcd):%d\n", trie_tree.Delete("abcd"));
    printf("trie_tree.Size:%d\n", trie_tree.Size());
    printf("trie_tree.PrefixNumber(ab):%d\n", trie_tree.PrefixNumber("ab"));
    printf("trie_tree.PrefixNumber(abc):%d\n", trie_tree.PrefixNumber("abc"));
    printf("trie_tree.PrefixNumber(abcf):%d\n", trie_tree.PrefixNumber("abcf"));

    return 0;
}

运行调试:
g++ -std=c++11 test.cpp && valgrind ./a.out

猜你喜欢

转载自blog.csdn.net/u012846486/article/details/80546643
今日推荐