一、问题描述
Description: Design a data structure that supports the following two operations:
void addWord(word) bool search(word)
search(word) can search a literal word or a regular expression string containing only letters
a-z
or.
and.
means it can represent any one letter.
For example:
addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true
Note:
You may assume that all words are consist of lowercase lettersa-z
.
设计一个数据结构,支持两种操作:
void addWord(word)
bool search(word)
search 操作可以查找字符串常量,或者一个包含.
的正则表达式。其中.
可以表示任何单个的字符。
假定所有的单词都是由小写字母组成。
二、解题报告
要实现一个具有字符串检索功能的词典,我们当然会想到
- 当要插入一个字符串时,将它插入到 Trie 树即可。
- 当要检索一个字符串时,若该字符串含有
.
,由于.
可以匹配当前层的所有节点,这时需要同时向下检索多条路径(使用递归)。
solution代码如下:
/*********Trie树的节点结构********/
class TrieNode {
public:
bool iskey; // 标记该节点是否代表关键字
TrieNode *children[26]; // 各个子节点
TrieNode() {
iskey = false;
for(int i=0; i<26; ++i)
children[i] = NULL;
}
};
/***************词典***************/
class WordDictionary {
public:
WordDictionary() {
root = new TrieNode();
}
// 插入一个单词
void addWord(string word) {
TrieNode* node = root;
for(int i=0; i<word.size(); ++i)
{
if(node->children[word[i]-'a'] == NULL)
{
node->children[word[i]-'a'] = new TrieNode();
}
node = node->children[word[i]-'a'];
}
node->iskey = true;
}
// 检索单词,可以包含'.'
bool search(string word) {
return searchWord(word, root, 0);
}
private:
TrieNode* root;
bool searchWord(string &word, TrieNode* node, int p) {
if(p == word.size())
return node->iskey;
if(word[p] == '.') { // 匹配任何字符
for(int i=0; i<26; ++i)
if(node->children[i] && searchWord(word, node->children[i], p+1))
return true;
return false;
}
else
return node->children[word[p]-'a'] && searchWord(word, node->children[word[p]-'a'], p+1);
}
};
LeetCode答案源代码:https://github.com/SongLee24/LeetCode