字典树(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
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;
};
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;
}
}
};
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