Skip to content

Commit e1613af

Browse files
authored
Merge pull request ephremdeme#222 from mnb27/master
TRIE ds in c++
2 parents a54a8da + 31d3365 commit e1613af

File tree

3 files changed

+392
-0
lines changed

3 files changed

+392
-0
lines changed

Trie/Auto_Complete_using_TRIE.cpp

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
// C++ program to demonstrate auto-complete feature
2+
// using Trie data structure.
3+
#include<bits/stdc++.h>
4+
using namespace std;
5+
6+
// Alphabet size (# of symbols)
7+
#define ALPHABET_SIZE (26)
8+
9+
// Converts key current character into index
10+
// use only 'a' through 'z' and lower case
11+
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')
12+
13+
// trie node
14+
struct TrieNode
15+
{
16+
struct TrieNode *children[ALPHABET_SIZE];
17+
18+
// isWordEnd is true if the node represents
19+
// end of a word
20+
bool isWordEnd;
21+
};
22+
23+
// Returns new trie node (initialized to NULLs)
24+
struct TrieNode *getNode(void)
25+
{
26+
struct TrieNode *pNode = new TrieNode;
27+
pNode->isWordEnd = false;
28+
29+
for (int i = 0; i < ALPHABET_SIZE; i++)
30+
pNode->children[i] = NULL;
31+
32+
return pNode;
33+
}
34+
35+
// If not present, inserts key into trie. If the
36+
// key is prefix of trie node, just marks leaf node
37+
void insert(struct TrieNode *root, const string key)
38+
{
39+
struct TrieNode *pCrawl = root;
40+
41+
for (int level = 0; level < key.length(); level++)
42+
{
43+
int index = CHAR_TO_INDEX(key[level]);
44+
if (!pCrawl->children[index])
45+
pCrawl->children[index] = getNode();
46+
47+
pCrawl = pCrawl->children[index];
48+
}
49+
50+
// mark last node as leaf
51+
pCrawl->isWordEnd = true;
52+
}
53+
54+
// Returns true if key presents in trie, else false
55+
bool search(struct TrieNode *root, const string key)
56+
{
57+
int length = key.length();
58+
struct TrieNode *pCrawl = root;
59+
for (int level = 0; level < length; level++)
60+
{
61+
int index = CHAR_TO_INDEX(key[level]);
62+
63+
if (!pCrawl->children[index])
64+
return false;
65+
66+
pCrawl = pCrawl->children[index];
67+
}
68+
69+
return (pCrawl != NULL && pCrawl->isWordEnd);
70+
}
71+
72+
// Returns 0 if current node has a child
73+
// If all children are NULL, return 1.
74+
bool isLastNode(struct TrieNode* root)
75+
{
76+
for (int i = 0; i < ALPHABET_SIZE; i++)
77+
if (root->children[i])
78+
return 0;
79+
return 1;
80+
}
81+
82+
// Recursive function to print auto-suggestions for given
83+
// node.
84+
void suggestionsRec(struct TrieNode* root, string currPrefix)
85+
{
86+
// found a string in Trie with the given prefix
87+
if (root->isWordEnd)
88+
{
89+
cout << currPrefix;
90+
cout << endl;
91+
}
92+
93+
// All children struct node pointers are NULL
94+
if (isLastNode(root))
95+
return;
96+
97+
for (int i = 0; i < ALPHABET_SIZE; i++)
98+
{
99+
if (root->children[i])
100+
{
101+
// append current character to currPrefix string
102+
currPrefix.push_back(97 + i);
103+
104+
// recur over the rest
105+
suggestionsRec(root->children[i], currPrefix);
106+
}
107+
}
108+
}
109+
110+
// print suggestions for given query prefix.
111+
int printAutoSuggestions(TrieNode* root, const string query)
112+
{
113+
struct TrieNode* pCrawl = root;
114+
115+
// Check if prefix is present and find the
116+
// the node (of last level) with last character
117+
// of given string.
118+
int level;
119+
int n = query.length();
120+
for (level = 0; level < n; level++)
121+
{
122+
int index = CHAR_TO_INDEX(query[level]);
123+
124+
// no string in the Trie has this prefix
125+
if (!pCrawl->children[index])
126+
return 0;
127+
128+
pCrawl = pCrawl->children[index];
129+
}
130+
131+
// If prefix is present as a word.
132+
bool isWord = (pCrawl->isWordEnd == true);
133+
134+
// If prefix is last node of tree (has no
135+
// children)
136+
bool isLast = isLastNode(pCrawl);
137+
138+
// If prefix is present as a word, but
139+
// there is no subtree below the last
140+
// matching node.
141+
if (isWord && isLast)
142+
{
143+
cout << query << endl;
144+
return -1;
145+
}
146+
147+
// If there are are nodes below last
148+
// matching character.
149+
if (!isLast)
150+
{
151+
string prefix = query;
152+
suggestionsRec(pCrawl, prefix);
153+
return 1;
154+
}
155+
}
156+
157+
// Driver Code
158+
int main()
159+
{
160+
struct TrieNode* root = getNode();
161+
insert(root, "hello");
162+
insert(root, "dog");
163+
insert(root, "hell");
164+
insert(root, "cat");
165+
insert(root, "a");
166+
insert(root, "hel");
167+
insert(root, "help");
168+
insert(root, "helps");
169+
insert(root, "helping");
170+
int comp = printAutoSuggestions(root, "hel");
171+
172+
if (comp == -1)
173+
cout << "No other strings found with this prefix\n";
174+
175+
else if (comp == 0)
176+
cout << "No string found with this prefix\n";
177+
178+
return 0;
179+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#define MAX_NODES 10000
2+
class Trie {
3+
struct Trienode
4+
{
5+
char val;
6+
int count;
7+
int endsHere;
8+
Trienode *child[26];
9+
};
10+
Trienode *root;
11+
12+
Trienode *getNode(int index)
13+
{
14+
Trienode *newnode = new Trienode;
15+
newnode->val = 'a'+index;
16+
newnode->count = newnode->endsHere = 0;
17+
for(int i=0;i<26;++i)
18+
newnode->child[i] = NULL;
19+
return newnode;
20+
}
21+
public:
22+
/** Initialize your data structure here. */
23+
Trie() {
24+
ios_base::sync_with_stdio(false);
25+
cin.tie(NULL);
26+
root = getNode('/'-'a');
27+
}
28+
29+
/** Inserts a word into the trie. */
30+
void insert(string word) {
31+
Trienode *curr = root;
32+
int index;
33+
for(int i=0;i<word.length();++i)
34+
{
35+
index = word[i]-'a';
36+
if(curr->child[index]==NULL)
37+
curr->child[index] = getNode(index);
38+
curr->child[index]->count +=1;
39+
curr = curr->child[index];
40+
}
41+
curr->endsHere +=1;
42+
}
43+
44+
/** Returns if the word is in the trie. */
45+
bool search(string word) {
46+
Trienode *curr = root;
47+
int index;
48+
for(int i=0;i<word.length();++i)
49+
{
50+
index = word[i]-'a';
51+
if(curr->child[index]==NULL)
52+
return false;
53+
curr = curr->child[index];
54+
}
55+
return (curr->endsHere > 0);
56+
}
57+
58+
/** Returns if there is any word in the trie that starts with the given prefix. */
59+
bool startsWith(string prefix) {
60+
Trienode *curr = root;
61+
int index;
62+
for(int i=0;i<prefix.length();++i)
63+
{
64+
index = prefix[i]-'a';
65+
if(curr->child[index]==NULL)
66+
return false;
67+
curr = curr->child[index];
68+
}
69+
return (curr->count > 0);
70+
}
71+
};
72+
73+
/**
74+
* Your Trie object will be instantiated and called as such:
75+
* Trie* obj = new Trie();
76+
* obj->insert(word);
77+
* bool param_2 = obj->search(word);
78+
* bool param_3 = obj->startsWith(prefix);
79+
*/

Trie/Trie.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
//CODE TO Count_Number_Of_Strings_With_Given_Prefix
2+
//Assumption: All characters are in lowercase
3+
#include<iostream>
4+
using namespace std;
5+
//#define NULL 0
6+
7+
struct Trienode
8+
{
9+
char data;
10+
int wc; //wc:word_count
11+
Trienode *child[26];
12+
};
13+
Trienode nodepool[100000]; //Pool of 100K Trienodes
14+
Trienode *root; //Root of Trie
15+
int poolcount; //Always points to next free Trienode
16+
17+
void init() //Initializer function
18+
{
19+
poolcount = 0;
20+
root = &nodepool[poolcount++];
21+
root->data = '/';
22+
for(register int i=0;i<26;++i)
23+
root->child[i] = NULL;
24+
}
25+
26+
Trienode *getNode(char c)
27+
{
28+
Trienode *newnode = &nodepool[poolcount++];
29+
newnode->data = c;
30+
for(register int i=0;i<26;++i)
31+
newnode->child[i] = NULL;
32+
newnode->wc=0;
33+
return newnode;
34+
}
35+
36+
void insert(char *s)
37+
{
38+
Trienode *curr = root;
39+
int index;
40+
for(int i=0; s[i]!='\0'; ++i)
41+
{
42+
index = s[i]-'a';
43+
if(curr->child[index]==NULL)
44+
curr->child[index] = getNode(s[i]);
45+
curr->child[index]->wc += 1;
46+
curr = curr->child[index];
47+
}
48+
}
49+
50+
bool search(char *s)
51+
{
52+
Trienode *curr = root;
53+
int index;
54+
for(int i=0; s[i]!='\0'; ++i)
55+
{
56+
index = s[i]-'a';
57+
if(curr->child[index]==NULL || curr->child[index]->wc == 0)
58+
return false;
59+
curr = curr->child[index];
60+
}
61+
return true;
62+
}
63+
64+
bool Triedelete(char *s)
65+
{
66+
if(search(s))
67+
{
68+
Trienode *curr = root;
69+
int index;
70+
for(int i=0; s[i]!='\0'; ++i)
71+
{
72+
index = s[i]-'a';
73+
curr->child[index]->wc -=1;
74+
curr = curr->child[index];
75+
}
76+
}
77+
}
78+
79+
int countPrefix(string s)
80+
{
81+
Trienode *curr = root;
82+
int index;
83+
for(int i=0; s[i]!='\0'; ++i)
84+
{
85+
index = s[i]-'a';
86+
if(curr->child[index]==NULL || curr->child[index]->wc == 0)
87+
return 0; //No string with given prefix is present
88+
curr = curr->child[index];
89+
}
90+
return curr->wc;
91+
}
92+
93+
int main()
94+
{
95+
init();
96+
char a[5] = {'a','r','m','y'};
97+
char b[5] = {'a','r','m'};
98+
char c[5] = {'a','r','m','s'};
99+
char d[5] = {'a','r','y'};
100+
char e[5] = {'a','m','y'};
101+
char f[5] = {'a','p','i'};
102+
103+
104+
insert(a);
105+
insert(b);
106+
insert(c);
107+
insert(d);
108+
insert(e);
109+
insert(f);
110+
111+
//cout<<search(b)<<"\n";
112+
113+
printf("No of strings with given prefix = %d\n",countPrefix("a"));
114+
printf("No of strings with given prefix = %d\n",countPrefix("ar"));
115+
printf("No of strings with given prefix = %d\n",countPrefix("arm"));
116+
printf("No of strings with given prefix = %d\n",countPrefix("army"));
117+
printf("No of strings with given prefix = %d\n",countPrefix("armi"));
118+
printf("No of strings with given prefix = %d\n",countPrefix("ary"));
119+
120+
cout<<"Deletion...STARTED\n";
121+
Triedelete(a);
122+
Triedelete(d);
123+
cout<<"DONE...\n\n";
124+
125+
126+
printf("No of strings with given prefix = %d\n",countPrefix("a"));
127+
printf("No of strings with given prefix = %d\n",countPrefix("ar"));
128+
printf("No of strings with given prefix = %d\n",countPrefix("arm"));
129+
printf("No of strings with given prefix = %d\n",countPrefix("army"));
130+
printf("No of strings with given prefix = %d\n",countPrefix("armi"));
131+
printf("No of strings with given prefix = %d\n",countPrefix("ary"));
132+
133+
return 0;
134+
}

0 commit comments

Comments
 (0)