forked from haoel/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 39
/
AddAndSearchWord.cpp
160 lines (143 loc) · 3.94 KB
/
AddAndSearchWord.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Source : https://leetcode.com/problems/add-and-search-word-data-structure-design/
// Author : Hao Chen
// Date : 2015-06-10
/**********************************************************************************
*
* 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.
*
* click to show hint.
*
* You should be familiar with how a Trie works. If not, please work on this problem: Implement Trie (Prefix Tree) first.
*
*
**********************************************************************************/
#include <string.h>
#include <iostream>
#include <string>
using namespace std;
const int MAX_CHARS = 26;
/*Trie Node*/
class TrieNode {
public:
TrieNode():isWord(false) {
memset(childern, 0, sizeof(childern));
}
TrieNode* & operator [] (char idx){
int i = (idx-'a') % MAX_CHARS;
return childern[i];
}
TrieNode* & operator [] (int idx){
int i = idx % MAX_CHARS;
return childern[i];
}
bool isWord;
private:
TrieNode* childern[MAX_CHARS];
};
/*Trie Tree*/
class TrieTree {
public:
TrieTree():root(new TrieNode()){ }
~TrieTree() { freeTree(root); }
void put(string &s) {
TrieNode* node = root;
for (int i=0; i<s.size(); i++){
if ((*node)[s[i]] == NULL){
(*node)[s[i]] = new TrieNode();
}
node = (*node)[s[i]];
}
node->isWord = true;
}
bool search(string &s){
return get(s, this->root);
}
private:
bool get(string &s, TrieNode* root, int idx=0){
TrieNode* node = root;
for (int i=idx; i<s.size(); i++){
if (s[i]!='.'){
node = (*node)[s[i]];
if (node == NULL) return false;
}else{
for (int j=0; j<MAX_CHARS; j++) {
TrieNode *p = (*node)[j];
if (p == NULL ) {
continue;//try next
}
// p!=NULL
if (i<s.size()-1) {
if (this->get(s, p, i+1)) {
return true;
}
continue; //try next
}
// p!=NULL && i == s.size()-1
if (p->isWord) {
return true;
}
}
return false;
}
}
return node->isWord;
}
private:
void freeTree(TrieNode* root){
for(int i=0; i<MAX_CHARS; i++){
if ((*root)[i]!=NULL){
freeTree((*root)[i]);
}
}
delete root;
}
TrieNode *root;
};
class WordDictionary {
public:
// Adds a word into the data structure.
void addWord(string word) {
tree.put(word);
}
// 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 tree.search(word);
}
private:
TrieTree tree;
};
// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary;
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");
int main()
{
WordDictionary wd;
wd.addWord("a");
cout << wd.search("a.") <<endl;;
cout << wd.search(".a") << endl;;
wd.addWord("bad");
cout << wd.search("bad") <<endl;;
cout << wd.search("b..") <<endl;;
return 0;
}