ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

字典树(Trie)

2022-07-07 17:09:19  阅读:175  来源: 互联网

标签:Node word cur Trie next root find 字典


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
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;
    }
};

标签:Node,word,cur,Trie,next,root,find,字典
来源: https://www.cnblogs.com/chengmf/p/16455319.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有