Skip to content

Commit

Permalink
trie completed
Browse files Browse the repository at this point in the history
  • Loading branch information
viren-sureja committed Jul 16, 2021
1 parent 79205c1 commit 612fbc1
Show file tree
Hide file tree
Showing 13 changed files with 1,399 additions and 0 deletions.
229 changes: 229 additions & 0 deletions 13_trie/01_construct_trie_from_scratch.cpp
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;
}
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;
}
Loading

0 comments on commit 612fbc1

Please sign in to comment.