字典树(Trie)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Trie最大的问题:空间!所以可以使用一下解决方案。
在这里插入图片描述
在这里插入图片描述

Code

#pragma once

#include <map>

class Node {
public:
    explicit Node() noexcept: isWord(false) {}

    explicit Node(bool isWord) : isWord(isWord), next() {}

public:
    bool isWord;
    std::map<char, Node> next;
};

class Trie {
public:
    explicit Trie() : size(0) {
        root = new Node();
    }

    ~Trie() noexcept {
        delete root;
        root = nullptr;
    }

    constexpr int getSize() const noexcept {
        return size;
    }

    void add(const std::string &word) {
        Node *cur = root;
        for (int i = 0; i < word.length(); ++i) {
            const char c = word.at(i);
            if (cur->next.find(c) == cur->next.end()) {     //如果找不到字母,就说明这个字母还没添加
                cur->next.insert(std::pair<char, Node>(c, Node()));
            }
            cur = &cur->next.find(c)->second;
        }

        if (!cur->isWord) { //如果以前不表示单词的结尾,否侧添加重复
            cur->isWord = true;
            size++;
        }
    }

    bool contains(const std::string &word) {
        const Node *cur = root;
        for (int i = 0; i < word.length(); ++i) {
            const char c = word.at(i);
            if (cur->next.find(c) == cur->next.end()) { //如果其中字母找不到,就说明单词不匹配直接看返回
                return false;
            }
            cur = &cur->next.find(c)->second;
        }
        return cur->isWord; //如果是 int interesting 类似的前缀, 所以返回记录是否为字母结尾的成员变量
    }

    //查询单词是否为前缀
    bool isPrefix(const std::string &prefix) {
        const Node *cur = root;
        for (int i = 0; i < prefix.length(); ++i) {
            const char c = prefix.at(i);
            if (cur->next.find(c) == cur->next.end()) {
                return false;
            }
            cur = &cur->next.find(c)->second;
        }
        return true;
    }

private:
    Node *root;
    int size;
};

LeetCode

208. 实现 Trie (前缀树)

class Trie {
public:
    /** Initialize your data structure here. */
    Trie() {
        root = new Node();
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        Node *cur = root;
        for (int i = 0; i < word.size(); ++i) {
            char c = word.at(i);
            if (cur->next.find(c) == cur->next.end()) {
                cur->next.insert(std::pair<char, Node>(c, Node()));
            }
            cur = &cur->next.find(c)->second;
        }

        if (!cur->isWord) {
            cur->isWord = true;
        }
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        Node *cur = root;
        for (int i = 0; i < word.size(); ++i) {
            char c = word.at(i);
            if (cur->next.find(c) == cur->next.end()) {
                return false;
            }
            cur = &cur->next.find(c)->second;
        }
        return cur->isWord;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        Node *cur = root;
        for (int i = 0; i < prefix.size(); ++i) {
            char c = prefix.at(i);
            if (cur->next.find(c) == cur->next.end()) {
                return false;
            }
            cur = &cur->next.find(c)->second;
        }
        return true;
    }
private:
    class Node {
    public:
        bool isWord;
        std::map<char, Node> next;

        Node() {
            isWord = false;
        }
    };

    Node *root;
};

211. 添加与搜索单词 - 数据结构设计

class WordDictionary {
public:
    /** Initialize your data structure here. */
    WordDictionary() {
        root = new Node();
    }
    
    /** Adds a word into the data structure. */
    void addWord(string word) {
        Node *cur = root;
        for (int i = 0; i < word.size(); ++i) {
            char c = word.at(i);
            if (cur->next.find(c) == cur->next.end()) {
                cur->next.insert(std::pair<char, Node>(c, Node()));
            }
            cur = &cur->next.find(c)->second;
        }
        cur->isWord = true;
    }
    
    /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
    bool search(string word) {
        return match(root, word, 0);
    }
private:
    class Node {
    public:
        bool isWord;
        std::map<char, Node> next;

        Node() {
            isWord = false;
        }
    };

    Node *root;
    
    bool match(Node *node, string word, int index) {
    	if (index == word.size()) {
    		return node->isWord;
    	}
    	char c = word.at(index);
    	if (c != '.') {
    		if (node->next.find(c) == node->next.end()) {
                return false;
            }
            return match(&node->next.find(c)->second, word, index + 1);
    	} else {
    		for(std::map<char, Node>::iterator iterator= node->next.begin();iterator != node->next.end();iterator++) {
             	if(match(&node->next.find(iterator->first)->second, word, index + 1)) {
             		return true;
             	}   
            }
            return false;
    	}    	
    }
};

677. 键值映射

class MapSum {
public:
    /** Initialize your data structure here. */
    MapSum() {
        root = new Node();
    }
    
    void insert(string key, int val) {
        Node *cur = root;
        for (int i = 0; i < key.size(); ++i) {
            char c = key.at(i);
            if (cur->next.find(c) == cur->next.end()) {
                cur->next.insert(std::pair<char, Node>(c, Node()));
            }
            cur = &cur->next.find(c)->second;
        }
        cur->value = val;
    }
    
    int sum(string prefix) {
        Node *cur = root;
        for (int i = 0; i < prefix.size(); i++) {
        	char c = prefix.at(i);
        	if (cur->next.find(c) == cur->next.end()) {
        		return 0;
        	}
        	cur = &cur->next.find(c)->second;
        }
        return sum(cur);
    }
private:
    class Node {
    public:
        int value;
        std::map<char, Node> next;

        Node() {
            value = 0;
        }
    };

    Node *root;
    
    int sum(Node *node) {
    	int res = node->value;
    	for(std::map<char, Node>::iterator iterator= node->next.begin();iterator != node->next.end();iterator++){
        	res += sum(&node->next.find(iterator->first)->second);  
        }
        return res;
    }
};
posted @ 2022-07-07 16:57  放飞梦想C  阅读(24)  评论(0编辑  收藏  举报