TheAlgorithms/C++
1.0.0
All the algorithms implemented in C++
Toggle main menu visibility
Loading...
Searching...
No Matches
trie_using_hashmap.cpp
Go to the documentation of this file.
1
13
#include <cassert>
14
#include <iostream>
15
#include <memory>
16
#include <stack>
17
#include <unordered_map>
18
#include <vector>
19
24
namespace
data_structures
{
25
31
namespace
trie_using_hashmap
{
32
39
class
Trie
{
40
private
:
44
struct
Node
{
45
std::unordered_map<char16_t, std::shared_ptr<Node>>
46
children
;
48
bool
word_end
=
false
;
49
};
50
51
std::shared_ptr<Node>
root_node
=
52
std::make_shared<Node>();
53
54
public
:
56
Trie
() =
default
;
57
62
void
insert
(
const
std::string& word) {
63
std::shared_ptr<Node> curr =
root_node
;
64
for
(
char
ch : word) {
65
if
(curr->children.find(ch) == curr->children.end()) {
66
curr->children[ch] = std::make_shared<Node>();
67
}
68
curr = curr->children[ch];
69
}
70
71
if
(!curr->word_end && curr !=
root_node
) {
72
curr->word_end =
true
;
73
}
74
}
75
82
bool
search
(
const
std::string& word) {
83
std::shared_ptr<Node> curr =
root_node
;
84
for
(
char
ch : word) {
85
if
(curr->children.find(ch) == curr->children.end()) {
86
return
false
;
87
}
88
curr = curr->children[ch];
89
if
(!curr) {
90
return
false
;
91
}
92
}
93
94
if
(curr->word_end) {
95
return
true
;
96
}
else
{
97
return
false
;
98
}
99
}
100
107
bool
startwith
(
const
std::string& prefix) {
108
std::shared_ptr<Node> curr =
root_node
;
109
for
(
char
ch : prefix) {
110
if
(curr->children.find(ch) == curr->children.end()) {
111
return
false
;
112
}
113
curr = curr->children[ch];
114
}
115
return
true
;
116
}
117
122
void
delete_word
(std::string word) {
123
std::shared_ptr<Node> curr =
root_node
;
124
std::stack<std::shared_ptr<Node>> nodes;
125
int
cnt = 0;
126
for
(
char
ch : word) {
127
if
(curr->children.find(ch) == curr->children.end()) {
128
return
;
129
}
130
if
(curr->word_end) {
131
cnt++;
132
}
133
134
nodes.push(curr->children[ch]);
135
curr = curr->children[ch];
136
}
137
// Delete only when it's a word, and it has children after
138
// or prefix in the line
139
if
(nodes.top()->word_end) {
140
nodes.top()->word_end =
false
;
141
}
142
// Delete only when it has no children after
143
// and also no prefix in the line
144
while
(!(nodes.top()->word_end) && nodes.top()->children.empty()) {
145
nodes.pop();
146
nodes.top()->children.erase(word.back());
147
word.pop_back();
148
}
149
}
150
160
std::vector<std::string>
get_all_words
(std::vector<std::string> results,
161
const
std::shared_ptr<Node>& element,
162
std::string prefix) {
163
if
(element->word_end) {
164
results.push_back(prefix);
165
}
166
if
(element->children.empty()) {
167
return
results;
168
}
169
for
(
auto
const
& x : element->children) {
170
std::string key =
""
;
171
key = x.first;
172
prefix += key;
173
174
results =
175
get_all_words
(results, element->children[x.first], prefix);
176
177
prefix.pop_back();
178
}
179
180
return
results;
181
}
182
188
std::vector<std::string>
predict_words
(
const
std::string& prefix) {
189
std::vector<std::string> result;
190
std::shared_ptr<Node> curr =
root_node
;
191
// traversing until the end of the given prefix in trie
192
193
for
(
char
ch : prefix) {
194
if
(curr->children.find(ch) == curr->children.end()) {
195
return
result;
196
}
197
198
curr = curr->children[ch];
199
}
200
201
// if the given prefix is the only word without children
202
if
(curr->word_end && curr->children.empty()) {
203
result.push_back(prefix);
204
return
result;
205
}
206
207
result =
get_all_words
(
208
result, curr,
209
prefix);
210
211
return
result;
212
}
213
};
214
}
// namespace trie_using_hashmap
215
}
// namespace data_structures
216
221
static
void
test
() {
222
data_structures::trie_using_hashmap::Trie
obj;
223
// Inserting data into trie using the insert
224
// method and testing it with search method
225
obj.
insert
(
"app"
);
226
obj.
insert
(
"abscond"
);
227
obj.
insert
(
"about"
);
228
obj.
insert
(
"apps"
);
229
obj.
insert
(
"apen"
);
230
obj.
insert
(
"apples"
);
231
obj.
insert
(
"apple"
);
232
obj.
insert
(
"approach"
);
233
obj.
insert
(
"bus"
);
234
obj.
insert
(
"buses"
);
235
obj.
insert
(
"Apple"
);
236
obj.
insert
(
"Bounce"
);
237
238
assert(!obj.
search
(
"appy"
));
239
std::cout <<
"appy is not a word in trie"
<< std::endl;
240
241
assert(!obj.
search
(
"car"
));
242
std::cout <<
"car is not a word in trie"
<< std::endl;
243
assert(obj.
search
(
"app"
));
244
assert(obj.
search
(
"apple"
));
245
assert(obj.
search
(
"apples"
));
246
assert(obj.
search
(
"apps"
));
247
assert(obj.
search
(
"apen"
));
248
assert(obj.
search
(
"approach"
));
249
assert(obj.
search
(
"about"
));
250
assert(obj.
search
(
"abscond"
));
251
assert(obj.
search
(
"bus"
));
252
assert(obj.
search
(
"buses"
));
253
assert(obj.
search
(
"Bounce"
));
254
assert(obj.
search
(
"Apple"
));
255
256
std::cout <<
"All the Inserted words are present in the trie"
<< std::endl;
257
258
// test for startwith prefix method
259
assert(!obj.
startwith
(
"approachs"
));
260
assert(obj.
startwith
(
"approach"
));
261
assert(obj.
startwith
(
"about"
));
262
assert(!obj.
startwith
(
"appy"
));
263
assert(obj.
startwith
(
"abscond"
));
264
assert(obj.
startwith
(
"bus"
));
265
assert(obj.
startwith
(
"buses"
));
266
assert(obj.
startwith
(
"Bounce"
));
267
assert(obj.
startwith
(
"Apple"
));
268
assert(obj.
startwith
(
"abs"
));
269
assert(obj.
startwith
(
"b"
));
270
assert(obj.
startwith
(
"bus"
));
271
assert(obj.
startwith
(
"Bo"
));
272
assert(obj.
startwith
(
"A"
));
273
assert(!obj.
startwith
(
"Ca"
));
274
275
assert(!obj.
startwith
(
"C"
));
276
277
std::cout <<
"All the tests passed for startwith method"
<< std::endl;
278
279
// test for predict_words/recommendation of words based on a given prefix
280
281
std::vector<std::string> pred_words = obj.
predict_words
(
"a"
);
282
283
for
(
const
std::string& str : obj.
predict_words
(
"a"
)) {
284
std::cout << str << std::endl;
285
}
286
assert(pred_words.size() == 8);
287
std::cout <<
"Returned all words that start with prefix a "
<< std::endl;
288
pred_words = obj.
predict_words
(
"app"
);
289
290
for
(
const
std::string& str : pred_words) {
291
std::cout << str << std::endl;
292
}
293
294
assert(pred_words.size() == 5);
295
std::cout <<
"Returned all words that start with prefix app "
<< std::endl;
296
pred_words = obj.
predict_words
(
"A"
);
297
298
for
(
const
std::string& str : pred_words) {
299
std::cout << str << std::endl;
300
}
301
302
assert(pred_words.size() == 1);
303
std::cout <<
"Returned all words that start with prefix A "
<< std::endl;
304
pred_words = obj.
predict_words
(
"bu"
);
305
306
for
(
const
std::string& str : pred_words) {
307
std::cout << str << std::endl;
308
}
309
310
assert(pred_words.size() == 2);
311
std::cout <<
"Returned all words that start with prefix bu "
<< std::endl;
312
313
// tests for delete method
314
315
obj.
delete_word
(
"app"
);
316
assert(!obj.
search
(
"app"
));
317
std::cout <<
"word app is deleted sucessful"
<< std::endl;
318
319
pred_words = obj.
predict_words
(
"app"
);
320
for
(
const
std::string& str : pred_words) {
321
std::cout << str << std::endl;
322
}
323
assert(pred_words.size() == 4);
324
std::cout <<
"app is deleted sucessful"
<< std::endl;
325
326
// test case for Chinese language
327
328
obj.
insert
(
"苹果"
);
329
assert(obj.
startwith
(
"苹"
));
330
pred_words = obj.
predict_words
(
"h"
);
331
332
assert(pred_words.size() == 0);
333
std::cout <<
"No word starts with prefix h in trie"
<< std::endl;
334
335
std::cout <<
"All tests passed"
<< std::endl;
336
}
337
342
int
main
() {
343
test
();
// run self-test implementaions
344
return
0;
345
}
test
void test()
Definition
caesar_cipher.cpp:100
data_structures::trie_using_hashmap::Trie
Trie class, implementation of trie using hashmap in each trie node for all the characters of char16_t...
Definition
trie_using_hashmap.cpp:39
data_structures::trie_using_hashmap::Trie::Trie
Trie()=default
< Constructor
data_structures::trie_using_hashmap::Trie::get_all_words
std::vector< std::string > get_all_words(std::vector< std::string > results, const std::shared_ptr< Node > &element, std::string prefix)
helper function to predict/recommend words that starts with a given prefix from the end of prefix's n...
Definition
trie_using_hashmap.cpp:160
data_structures::trie_using_hashmap::Trie::root_node
std::shared_ptr< Node > root_node
declaring root node of trie
Definition
trie_using_hashmap.cpp:51
data_structures::trie_using_hashmap::Trie::insert
void insert(const std::string &word)
insert the string into the trie
Definition
trie_using_hashmap.cpp:62
data_structures::trie_using_hashmap::Trie::delete_word
void delete_word(std::string word)
delete a word/string from a trie
Definition
trie_using_hashmap.cpp:122
data_structures::trie_using_hashmap::Trie::search
bool search(const std::string &word)
search a word/string inside the trie
Definition
trie_using_hashmap.cpp:82
data_structures::trie_using_hashmap::Trie::predict_words
std::vector< std::string > predict_words(const std::string &prefix)
predict/recommend a word that starts with a given prefix
Definition
trie_using_hashmap.cpp:188
data_structures::trie_using_hashmap::Trie::startwith
bool startwith(const std::string &prefix)
search a word/string that starts with a given prefix
Definition
trie_using_hashmap.cpp:107
main
int main()
Main function.
Definition
generate_parentheses.cpp:110
data_structures
for IO operations
trie_using_hashmap
Functions for Trie data structure using hashmap implementation.
data_structures::trie_using_hashmap::Trie::Node
struct representing a trie node.
Definition
trie_using_hashmap.cpp:44
data_structures::trie_using_hashmap::Trie::Node::children
std::unordered_map< char16_t, std::shared_ptr< Node > > children
Definition
trie_using_hashmap.cpp:46
data_structures::trie_using_hashmap::Trie::Node::word_end
bool word_end
boolean variable to represent the node end
Definition
trie_using_hashmap.cpp:48
data_structures
trie_using_hashmap.cpp
Generated by
1.18.0