-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrie.cpp
176 lines (144 loc) · 3.97 KB
/
trie.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include<iostream>
using namespace std;
// considering only lowercase letters
#define ALPHABET_SIZE (26)
// Converts key current character into index
// use only 'a' through 'z' and lower case
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
// trie node
struct TrieNode
{
struct TrieNode *children[ALPHABET_SIZE];
// isWordEnd is true if the node represents
// end of a word
bool isWordEnd;
};
class Tries {
TrieNode *root;
// helper functions
// create a new node
TrieNode* makeNode() {
TrieNode *newNode = new TrieNode;
newNode->isWordEnd = false;
for(int i = 0; i < 26; i++)
newNode->children[i] = NULL;
return newNode;
}
// check if the current node is the last node
bool isLastNode(TrieNode* curr) {
for (int i = 0; i < ALPHABET_SIZE; i++)
if (curr->children[i])
return false;
return true;
}
public:
// constructor
Tries() {
root = makeNode();
}
void insert(string);
bool search(string);
int printAutoSuggestions(const string);
void dfs(TrieNode*, string);
};
// Driver Code
int main()
{
Tries *newTrie = new Tries;
newTrie->insert("diamond");
newTrie->insert("district");
newTrie->insert("dibora");
newTrie->insert("hiii");
newTrie->insert("how");
newTrie->insert("home");
newTrie->insert("damage");
newTrie->insert("dose");
newTrie->insert("distance");
int comp = newTrie->printAutoSuggestions("di");
if (comp == -1)
cout << "No other strings found with this prefix\n";
else if (comp == 0)
cout << "No string found with this prefix\n";
return 0;
}
void Tries::insert(string word) {
TrieNode *parent = root;
//traverse the Trie and create nodes if not present
for(int i = 0; i < word.size(); i++) {
int index = CHAR_TO_INDEX(word[i]);
if(!parent->children[index]) {
parent->children[index] = makeNode();
}
parent = parent->children[index];
}
// mark last node as end of word
parent->isWordEnd = true;
}
// search for an exact match
bool Tries::search(string word) {
TrieNode *parent = root;
// Traverse the Trie and return false if current node doesnt exists
for(int i = 0; i < word.size(); i++) {
int index = CHAR_TO_INDEX(word[i]);
if(!parent->children[index]) {
return false;
}
parent = parent->children[index];
}
// last should not be null and also should be end of the word
return (parent != NULL && parent->isWordEnd);
}
// search for all possible matches
void Tries::dfs(TrieNode* curr, string currPrefix) {
// found a match
if (curr->isWordEnd) {
std::cout << currPrefix;
std::cout << endl;
}
// leaf node
if (isLastNode(curr)) {
return;
}
for (int i = 0; i < ALPHABET_SIZE; i++) {
if (curr->children[i]) {
// append the current character
currPrefix.push_back(97 + i);
// dfs for the new formed string
dfs(curr->children[i], currPrefix);
// remove the last added character
// for dfs over other nodes
currPrefix.pop_back();
}
}
}
// print suggestions for given query prefix.
int Tries::printAutoSuggestions(const string query) {
struct TrieNode* parent = root;
// traverse Trie and find the last node
// corresponding to the last character of the query
for (int i = 0; i < query.size(); i++) {
int index = CHAR_TO_INDEX(query[i]);
// no match found
if (!parent->children[index])
return 0;
parent = parent->children[index];
}
// given word is present
bool isWord = (parent->isWordEnd == true);
// is last node of the Trie
bool isLast = isLastNode(parent);
// If query present as a word in the dictionary, but
// there is no other matchings
if (isWord && isLast) {
std::cout << query << endl;
return 1;
}
// if ther are more matchings
if (!isLast)
{
string matches = query;
dfs(parent, matches);
return 2;
}
return 2;
}