Skip to content

Commit

Permalink
Trie ds problem
Browse files Browse the repository at this point in the history
  • Loading branch information
harrypotter0 committed Jan 24, 2018
1 parent 74713f8 commit 1d147f5
Show file tree
Hide file tree
Showing 2 changed files with 340 additions and 0 deletions.
151 changes: 151 additions & 0 deletions CP/Codeforces Round #457 (Div. 2)/prob4.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#include <bits/stdc++.h>
using namespace std;

typedef long long lint; typedef pair<int, int> ii;
const int MOD = 1'000'000'007, MOD2 = 1'000'000'009;
const int INF = 0x3f3f3f3f; const lint BINF = 0x3f3f3f3f3f3f3f3fLL;

struct StringTrie{

StringTrie *chi[26];
int dat;

StringTrie(){
for(int i=0;i<26;i++) chi[i] = nullptr;
dat = -1;
}

StringTrie(StringTrie *old){
for(int i=0;i<26;i++) chi[i] = old->chi[i];
dat = old->dat;
}

StringTrie *set(string &s, int val, int pos = 0){
StringTrie *rt = new StringTrie(this);
if(pos >= s.size()){
//printf("choot1\n", );
rt->dat = val;
}else{
//printf("choot2\n", );
int v = s[pos] - 'a';
if(!chi[v]) chi[v] = new StringTrie();
rt->chi[v] = chi[v]->set(s, val, pos + 1);
}
return rt;
}

int get(string &s, int pos = 0){
if(pos >= s.size()){
return dat;
}else{
int v = s[pos] - 'a';
if(!chi[v]) return -1;
return chi[v]->get(s, pos + 1);
}
}

};

struct BinaryTrie{

BinaryTrie *chi[2];
int dat;

BinaryTrie(){
chi[0] = chi[1] = nullptr;
dat = 0;
}

BinaryTrie(BinaryTrie *old){
chi[0] = old->chi[0];
chi[1] = old->chi[1];
dat = old->dat;
}

BinaryTrie *add(int s, int val, int pos = 30){
BinaryTrie *rt = new BinaryTrie(this);
rt->dat += val;
if(pos >= 0){
int v = (s >> pos) & 1;
if(!chi[v]) chi[v] = new BinaryTrie();
rt->chi[v] = chi[v]->add(s, val, pos - 1);
}
return rt;
}

int get(int s, int pos = 30){
if(pos < 0){
return 0;
}else{
int v = (s >> pos) & 1;
if(v){
int ans = 0;
// add 0
if(chi[0]) ans += chi[0]->dat;
// query 1
if(chi[1]) ans += chi[1]->get(s, pos - 1);
return ans;
}else{
// query 0
if(chi[0])
return chi[0]->get(s, pos - 1);
else
return 0;
}
}
}

};

int solve(){
int q; cin >> q;
StringTrie **st = new StringTrie*[q + 5];
BinaryTrie **bt = new BinaryTrie*[q + 5];
st[0] = new StringTrie();
bt[0] = new BinaryTrie();
for(int i=1;i<=q;i++){
string op; cin >> op;
if(op == "set"){
string str; int val;
cin >> str >> val;
int x = st[i-1]->get(str);
st[i] = st[i-1]->set(str, val);
if(x >= 0){
bt[i] = bt[i-1]->add(x, -1);
bt[i] = bt[i]->add(val, 1);
}else{
bt[i] = bt[i-1]->add(val, 1);
}
}else if(op == "remove"){
string str; cin >> str;
int x = st[i-1]->get(str);
st[i] = st[i-1]->set(str, -1);
if(x >= 0)
bt[i] = bt[i-1]->add(x, -1);
else
bt[i] = bt[i-1];
}else if(op == "undo"){
int x; cin >> x;
st[i] = st[i - x - 1];
bt[i] = bt[i - x - 1];
}else{
st[i] = st[i - 1];
bt[i] = bt[i - 1];
string str; cin >> str;
int x = st[i]->get(str);
if(x >= 0)
cout << bt[i]->get(x) << endl;
else
cout << -1 << endl;
}
}
return 0;
}

int main(){
ios::sync_with_stdio(0);
// int t; cin >> t; while(t--)
solve();
// cout << (solve() ? "YES" : "NO") << endl;
return 0;
}
189 changes: 189 additions & 0 deletions tree/trie.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#include <iostream>

// define character size
#define CHAR_SIZE 128

// A Class representing a Trie node
class Trie
{
public:
bool isLeaf;
Trie* character[CHAR_SIZE];

// Constructor
Trie()
{
this->isLeaf = false;

for (int i = 0; i < CHAR_SIZE; i++)
this->character[i] = nullptr;
}

void insert(std::string);
bool deletion(Trie*&, std::string);
bool search(std::string);
bool haveChildren(Trie const*);
};

// Iterative function to insert a key in the Trie
void Trie::insert(std::string key)
{
// start from root node
Trie* curr = this;
for (int i = 0; i < key.length(); i++)
{
// create a new node if path doesn't exists
if (curr->character[key[i]] == nullptr)
curr->character[key[i]] = new Trie();

// go to next node
curr = curr->character[key[i]];
}

// mark current node as leaf
curr->isLeaf = true;
}

// Iterative function to search a key in Trie. It returns true
// if the key is found in the Trie, else it returns false
bool Trie::search(std::string key)
{
// return false if Trie is empty
if (this == nullptr)
return false;

Trie* curr = this;
for (int i = 0; i < key.length(); i++)
{
// go to next node
curr = curr->character[key[i]];

// if string is invalid (reached end of path in Trie)
if (curr == nullptr)
return false;
}

// if current node is a leaf and we have reached the
// end of the string, return true
return curr->isLeaf;
}

// returns true if given node has any children
bool Trie::haveChildren(Trie const* curr)
{
for (int i = 0; i < CHAR_SIZE; i++)
if (curr->character[i])
return true; // child found

return false;
}

// Recursive function to delete a key in the Trie
bool Trie::deletion(Trie*& curr, std::string key)
{
// return if Trie is empty
if (curr == nullptr)
return false;

// if we have not reached the end of the key
if (key.length())
{
// recurse for the node corresponding to next character in the key
// and if it returns true, delete current node (if it is non-leaf)

if (curr != nullptr &&
curr->character[key[0]] != nullptr &&
deletion(curr->character[key[0]], key.substr(1)) &&
curr->isLeaf == false)
{
if (!haveChildren(curr))
{
delete curr;
curr = nullptr;
return true;
}
else {
return false;
}
}
}

// if we have reached the end of the key
if (key.length() == 0 && curr->isLeaf)
{
// if current node is a leaf node and don't have any children
if (!haveChildren(curr))
{
// delete current node
delete curr;
curr = nullptr;

// delete non-leaf parent nodes
return true;
}

// if current node is a leaf node and have children
else
{
// mark current node as non-leaf node (DON'T DELETE IT)
curr->isLeaf = false;

// don't delete its parent nodes
return false;
}
}

return false;
}

// C++ implementation of Trie Data Structure - Insertion, Searching and Deletion
int main()
{
Trie* head = new Trie();

head->insert("hello");
std::cout << head->search("hello") << " "; // print 1

head->insert("helloworld");
std::cout << head->search("helloworld") << " "; // print 1

std::cout << head->search("helll") << " "; // print 0 (Not found)

head->insert("hell");
std::cout << head->search("hell") << " "; // print 1

head->insert("h");
std::cout << head->search("h"); // print 1

std::cout << std::endl;

head->deletion(head, "hello");
std::cout << head->search("hello") << " "; // print 0 ("hello" deleted)
std::cout << head->search("helloworld") << " "; // print 1
std::cout << head->search("hell"); // print 1

std::cout << std::endl;

head->deletion(head, "h");
std::cout << head->search("h") << " "; // print 0 ("h" deleted)
std::cout << head->search("hell") << " "; // print 1
std::cout << head->search("helloworld"); // print 1

std::cout << std::endl;

head->deletion(head, "helloworld");
std::cout << head->search("helloworld") << " "; // print 0 ("helloworld" deleted)
std::cout << head->search("hell") << " "; // print 1

head->deletion(head, "hell");
std::cout << head->search("hell"); // print 0

std::cout << std::endl;

if (head == nullptr)
std::cout << "Trie empty!!\n"; // Trie is empty now

std::cout << head->search("hell"); // print 0

return 0;
}

0 comments on commit 1d147f5

Please sign in to comment.