-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
79205c1
commit 612fbc1
Showing
13 changed files
with
1,399 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
/* | ||
[intro]: https://youtu.be/6PX6wqDQE20?list=PLEJXowNB4kPyi859E6qGUs7jlpQehJndl | ||
[insertion and search]: https://youtu.be/0k79LqIaHyQ?list=PLEJXowNB4kPyi859E6qGUs7jlpQehJndl | ||
[deletion]: https://youtu.be/ict1UawpXMM?list=PLEJXowNB4kPyi859E6qGUs7jlpQehJndl | ||
link (): https://www.geeksforgeeks.org/trie-insert-and-search/ | ||
*/ | ||
|
||
|
||
// ----------------------------------------------------------------------------------------------------------------------- // | ||
//CODE TO Count_Number_Of_Strings_With_Given_Prefix | ||
//Assumption: All characters are in lowercase | ||
#include<iostream> | ||
using namespace std; | ||
//#define NULL 0 | ||
|
||
struct Trienode | ||
{ | ||
char data; | ||
int wc; //wc:word_count | ||
Trienode* child[26]; | ||
}; | ||
Trienode nodepool[100000]; //Pool of 100K Trienodes | ||
Trienode* root; //Root of Trie | ||
int poolcount; //Always points to next free Trienode | ||
|
||
void init() //Initializer function | ||
{ | ||
poolcount = 0; | ||
root = &nodepool[poolcount++]; | ||
root->data = '/'; | ||
for (register int i = 0;i < 26;++i) | ||
root->child[i] = NULL; | ||
} | ||
|
||
Trienode* getNode(char c) | ||
{ | ||
Trienode* newnode = &nodepool[poolcount++]; | ||
newnode->data = c; | ||
for (register int i = 0;i < 26;++i) | ||
newnode->child[i] = NULL; | ||
newnode->wc = 0; | ||
return newnode; | ||
} | ||
|
||
void insert(char* s) | ||
{ | ||
Trienode* curr = root; | ||
int index; | ||
for (int i = 0; s[i] != '\0'; ++i) | ||
{ | ||
index = s[i] - 'a'; | ||
if (curr->child[index] == NULL) | ||
curr->child[index] = getNode(s[i]); | ||
curr->child[index]->wc += 1; | ||
curr = curr->child[index]; | ||
} | ||
} | ||
|
||
bool search(char* s) | ||
{ | ||
Trienode* curr = root; | ||
int index; | ||
for (int i = 0; s[i] != '\0'; ++i) | ||
{ | ||
index = s[i] - 'a'; | ||
if (curr->child[index] == NULL || curr->child[index]->wc == 0) | ||
return false; | ||
curr = curr->child[index]; | ||
} | ||
return true; | ||
} | ||
|
||
bool Triedelete(char* s) | ||
{ | ||
if (search(s)) | ||
{ | ||
Trienode* curr = root; | ||
int index; | ||
for (int i = 0; s[i] != '\0'; ++i) | ||
{ | ||
index = s[i] - 'a'; | ||
curr->child[index]->wc -= 1; | ||
curr = curr->child[index]; | ||
} | ||
} | ||
} | ||
|
||
int countPrefix(string s) | ||
{ | ||
Trienode* curr = root; | ||
int index; | ||
for (int i = 0; s[i] != '\0'; ++i) | ||
{ | ||
index = s[i] - 'a'; | ||
if (curr->child[index] == NULL || curr->child[index]->wc == 0) | ||
return 0; //No string with given prefix is present | ||
curr = curr->child[index]; | ||
} | ||
return curr->wc; | ||
} | ||
|
||
int main() | ||
{ | ||
init(); | ||
char a[5] = { 'a','r','m','y' }; | ||
char b[5] = { 'a','r','m' }; | ||
char c[5] = { 'a','r','m','s' }; | ||
char d[5] = { 'a','r','y' }; | ||
char e[5] = { 'a','m','y' }; | ||
char f[5] = { 'a','p','i' }; | ||
|
||
|
||
insert(a); | ||
insert(b); | ||
insert(c); | ||
insert(d); | ||
insert(e); | ||
insert(f); | ||
|
||
//cout<<search(b)<<"\n"; | ||
|
||
printf("No of strings with given prefix = %d\n", countPrefix("a")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("ar")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("arm")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("army")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("armi")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("ary")); | ||
|
||
cout << "Deletion...STARTED\n"; | ||
Triedelete(a); | ||
Triedelete(d); | ||
cout << "DONE...\n\n"; | ||
|
||
|
||
printf("No of strings with given prefix = %d\n", countPrefix("a")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("ar")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("arm")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("army")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("armi")); | ||
printf("No of strings with given prefix = %d\n", countPrefix("ary")); | ||
|
||
return 0; | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/* | ||
alternative way | ||
*/ | ||
|
||
class Node { | ||
public: | ||
char data; | ||
unordered_map<char, Node*> m; | ||
bool isTerminal; | ||
|
||
Node(char d) { | ||
data = d; | ||
isTerminal = false; | ||
} | ||
}; | ||
|
||
class Trie { | ||
public: | ||
Node* root; | ||
Trie() { | ||
root = new Node('\0'); | ||
} | ||
|
||
void insert(string word) { | ||
Node* temp = root; | ||
|
||
for (char ch : word) { | ||
if (temp->m.count(ch) == 0) { | ||
temp->m[ch] = new Node(ch); | ||
} | ||
temp = temp->m[ch]; | ||
} | ||
temp->isTerminal = true; | ||
} | ||
|
||
bool search(string word) { | ||
Node* temp = root; | ||
|
||
for (char ch : word) { | ||
if (temp->m.count(ch) == 0) return false; | ||
temp = temp->m[ch]; | ||
} | ||
return temp->isTerminal; | ||
} | ||
|
||
// void delete(string word) {} | ||
}; | ||
|
||
int main() { | ||
string words[] = { "viren", "shiva", "tgvs", "new", "news" }; | ||
|
||
Trie t; | ||
for (auto w : words) { | ||
t.insert(w); | ||
} | ||
|
||
int q; | ||
cin >> q; | ||
|
||
string search_word; | ||
while (q--) { | ||
cin >> search_word; | ||
if (t.search(search_word)) { | ||
cout << "Yes, it is present" << endl; | ||
} | ||
else cout << "No, it is not present" << endl; | ||
} | ||
|
||
return 0; | ||
} |
112 changes: 112 additions & 0 deletions
112
13_trie/02_Find_shortest_unique_prefix_for_every_word_in_a_given_list.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/* | ||
https://www.geeksforgeeks.org/find-all-shortest-unique-prefixes-to-represent-each-word-in-a-given-list/ | ||
*/ | ||
|
||
|
||
// ----------------------------------------------------------------------------------------------------------------------- // | ||
// C++ program to print all prefixes that | ||
// uniquely represent words. | ||
#include<bits/stdc++.h> | ||
using namespace std; | ||
|
||
#define MAX 256 | ||
|
||
// Maximum length of an input word | ||
#define MAX_WORD_LEN 500 | ||
|
||
// Trie Node. | ||
struct trieNode | ||
{ | ||
struct trieNode* child[MAX]; | ||
int freq; // To store frequency | ||
}; | ||
|
||
// Function to create a new trie node. | ||
struct trieNode* newTrieNode(void) | ||
{ | ||
struct trieNode* newNode = new trieNode; | ||
newNode->freq = 1; | ||
for (int i = 0; i < MAX; i++) | ||
newNode->child[i] = NULL; | ||
return newNode; | ||
} | ||
|
||
// Method to insert a new string into Trie | ||
void insert(struct trieNode* root, string str) | ||
{ | ||
// Length of the URL | ||
int len = str.length(); | ||
struct trieNode* pCrawl = root; | ||
|
||
// Traversing over the length of given str. | ||
for (int level = 0; level < len; level++) | ||
{ | ||
// Get index of child node from current character | ||
// in str. | ||
int index = str[level]; | ||
|
||
// Create a new child if not exist already | ||
if (!pCrawl->child[index]) | ||
pCrawl->child[index] = newTrieNode(); | ||
else | ||
(pCrawl->child[index]->freq)++; | ||
|
||
// Move to the child | ||
pCrawl = pCrawl->child[index]; | ||
} | ||
} | ||
|
||
// This function prints unique prefix for every word stored | ||
// in Trie. Prefixes one by one are stored in prefix[]. | ||
// 'ind' is current index of prefix[] | ||
void findPrefixesUtil(struct trieNode* root, char prefix[], | ||
int ind) | ||
{ | ||
// Corner case | ||
if (root == NULL) | ||
return; | ||
|
||
// Base case | ||
if (root->freq == 1) | ||
{ | ||
prefix[ind] = '\0'; | ||
cout << prefix << " "; | ||
return; | ||
} | ||
|
||
for (int i = 0; i < MAX; i++) | ||
{ | ||
if (root->child[i] != NULL) | ||
{ | ||
prefix[ind] = i; | ||
findPrefixesUtil(root->child[i], prefix, ind + 1); | ||
} | ||
} | ||
} | ||
|
||
// Function to print all prefixes that uniquely | ||
// represent all words in arr[0..n-1] | ||
void findPrefixes(string arr[], int n) | ||
{ | ||
// Construct a Trie of all words | ||
struct trieNode* root = newTrieNode(); | ||
root->freq = 0; | ||
for (int i = 0; i < n; i++) | ||
insert(root, arr[i]); | ||
|
||
// Create an array to store all prefixes | ||
char prefix[MAX_WORD_LEN]; | ||
|
||
// Print all prefixes using Trie Traversal | ||
findPrefixesUtil(root, prefix, 0); | ||
} | ||
|
||
// Driver function. | ||
int main() | ||
{ | ||
string arr[] = { "zebra", "dog", "duck", "dove" }; | ||
int n = sizeof(arr) / sizeof(arr[0]); | ||
findPrefixes(arr, n); | ||
|
||
return 0; | ||
} |
Oops, something went wrong.