-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathautoComplete.cpp
181 lines (149 loc) · 3.87 KB
/
autoComplete.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
177
178
179
180
181
#include<bits/stdc++.h>
using namespace std;
// Alphabet size (# of symbols)
#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;
};
// Returns new trie node (initialized to NULLs)
struct TrieNode *getNode(void)
{
struct TrieNode *pNode = new TrieNode;
pNode->isWordEnd = false;
for (int i = 0; i < ALPHABET_SIZE; i++)
pNode->children[i] = NULL;
return pNode;
}
// If not present, inserts key into trie. If the
// key is prefix of trie node, just marks leaf node
void insert(struct TrieNode *root, const string key)
{
struct TrieNode *pCrawl = root;
for (int level = 0; level < key.length(); level++)
{
int index = CHAR_TO_INDEX(key[level]);
if (!pCrawl->children[index])
pCrawl->children[index] = getNode();
pCrawl = pCrawl->children[index];
}
// mark last node as leaf
pCrawl->isWordEnd = true;
}
// Returns true if key presents in trie, else false
bool search(struct TrieNode *root, const string key)
{
int length = key.length();
struct TrieNode *pCrawl = root;
for (int level = 0; level < length; level++)
{
int index = CHAR_TO_INDEX(key[level]);
if (!pCrawl->children[index])
return false;
pCrawl = pCrawl->children[index];
}
return (pCrawl != NULL && pCrawl->isWordEnd);
}
// Returns 0 if current node has a child
// If all children are NULL, return 1.
bool isLastNode(struct TrieNode* root)
{
for (int i = 0; i < ALPHABET_SIZE; i++)
if (root->children[i])
return 0;
return 1;
}
// Recursive function to print auto-suggestions for given
// node.
void suggestionsRec(struct TrieNode* root, string currPrefix)
{
// found a string in Trie with the given prefix
if (root->isWordEnd)
{
cout << currPrefix;
cout << endl;
}
// All children struct node pointers are NULL
if (isLastNode(root))
return;
for (int i = 0; i < ALPHABET_SIZE; i++)
{
if (root->children[i])
{
// append current character to currPrefix string
currPrefix.push_back(97 + i);
// recur over the rest
suggestionsRec(root->children[i], currPrefix);
}
}
}
// print suggestions for given query prefix.
int printAutoSuggestions(TrieNode* root, const string query)
{
struct TrieNode* pCrawl = root;
// Check if prefix is present and find the
// the node (of last level) with last character
// of given string.
int level;
int n = query.length();
for (level = 0; level < n; level++)
{
int index = CHAR_TO_INDEX(query[level]);
// no string in the Trie has this prefix
if (!pCrawl->children[index])
return 0;
pCrawl = pCrawl->children[index];
}
// If prefix is present as a word.
bool isWord = (pCrawl->isWordEnd == true);
// If prefix is last node of tree (has no
// children)
bool isLast = isLastNode(pCrawl);
// If prefix is present as a word, but
// there is no subtree below the last
// matching node.
if (isWord && isLast)
{
cout << query << endl;
return -1;
}
// If there are are nodes below last
// matching character.
if (!isLast)
{
string prefix = query;
suggestionsRec(pCrawl, prefix);
return 1;
}
}
// Driver Code
int main()
{
struct TrieNode* root = getNode();
insert(root, "hello");
insert(root, "dog");
insert(root, "hell");
insert(root, "cat");
insert(root, "a");
insert(root, "hel");
insert(root, "help");
insert(root, "helps");
insert(root, "helping");
insert(root, "nonchalant");
string s;
cout<<"enter data\n";
cin>>s;
int comp = printAutoSuggestions(root, s);
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;
}