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 .. A . 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 letters a-z.
You should be familiar with how a Trie works. If not, please work on this problem: Implement Trie (Prefix Tree) first.
const int leafSize = 26;
class TrieNode
{
public:
TrieNode():isLeaf(false)
{
fill_n(children,leafSize,nullptr);
}
bool isLeaf;
TrieNode *children[leafSize];
};
class WordDictionary {
TrieNode *root;
public:
WordDictionary():root(new TrieNode)
{
}
// Adds a word into the data structure.
void addWord(string word) {
TrieNode *index = root;
TrieNode *temp = nullptr;
std::size_t i = 0;
for(;i < word.size();++i)
{
temp = index->children[word[i] - 'a'];
if(nullptr == temp)
index->children[word[i] - 'a'] = new TrieNode;
index = index->children[word[i] - 'a'];
}
index->isLeaf = 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 search(word,root);
}
bool search(string word,TrieNode *p) {
TrieNode *index = p;
TrieNode *temp = nullptr;
std::size_t i = 0;
for(;i < word.size();++i)
{
if(word[i] == '.')
{
for(int j = 0;j < leafSize;++j)
if(index->children[j] && search(word.substr(i + 1),index->children[j]))
return true;
return false;
}
else
{
temp = index->children[word[i] - 'a'];
if(nullptr == temp)
return false;
index = index->children[word[i] - 'a'];
}
}
return index->isLeaf;
}
};
// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary;
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");
浙公网安备 33010602011771号