设计一个数据结构,支持如下两个操作:
- 添加单词: addWord(word)
- 搜索单词: bool search(word)
搜索单词时,可以按照普通的方式搜索单词(原始单词),或正则表达式的方式搜索单词,添加的单词只包含小写字符’a’-‘z’; 搜索时,只包含小写字符’a’-‘z’或’.’。’.'代表任意一个小写字符。
例如:
addWord(“bad”)
addWord(“dad”)
addWord(“mad”)
search(“pad”)->false
search(“bad”)->true
search(".ad")->true
search(“b…”)->true
#include<vector>
#include<string>
#define MAX_TRIE_CHAR_NUM 26
struct TrieNode
{
TrieNode* child[MAX_TRIE_CHAR_NUM];
bool is_end;
TrieNode() : is_end(false)
{
for (int i = 0; i < MAX_TRIE_CHAR_NUM; i++)
{
child[i] = 0;
}
}
};
bool search_trie(TrieNode* node, const char* word)
{
if (*word=='\0')
{
if (node->is_end)
{
return true;
}
}
if (*word=='.')
{
for (int i = 0; i < MAX_TRIE_CHAR_NUM; i++)
{
if (node->child[i]&&search_trie(node->child[i], word+1))
{
return true;
}
}
}
else
{
int pos = *word - 'a';
if (node->child[pos]&&search_trie(node->child[pos],word+1))
{
return true;
}
}
return false;
}
class TrieTree
{
public:
TrieTree() {}
~TrieTree()
{
for (int i = 0; i < _node_vec.size(); i++)
{
delete _node_vec[i];
}
}
TrieNode _root;
void insert(const char* word)
{
TrieNode* ptr = &_root;
while (*word)
{
int pos = *word - 'a';
if (!ptr->child[pos])
{
ptr->child[pos] = new_node();
}
ptr = ptr->child[pos];
word++;
}
ptr->is_end = true;
}
private:
TrieNode* new_node()
{
TrieNode* node = new TrieNode();
_node_vec.push_back(node);
return node;
}
std::vector<TrieNode*> _node_vec;
};
class WorkDictionary
{
public:
WorkDictionary() {}
~WorkDictionary() {}
void addWord(std::string word)
{
_trie_tree.insert(word.c_str());
}
bool search(std::string word)
{
return search_trie(&_trie_tree._root, word.c_str());
}
private:
TrieTree _trie_tree;
};
int main()
{
WorkDictionary word_dictionary;
word_dictionary.addWord("bad");
word_dictionary.addWord("dad");
word_dictionary.addWord("mad");
printf("%d\n", word_dictionary.search("pad"));
printf("%d\n", word_dictionary.search("bad"));
printf("%d\n", word_dictionary.search(".ad"));
printf("%d\n", word_dictionary.search("b.."));
return 0;
}
运行结果为:
0
1
1
1