Segmentation fault in trie implementation using vector c++ - c++

#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define LOWERCASE_ALPHABET_SiZE 26
typedef int (*ptr) (char );
inline int charToIndex(char a) { return a - 'a'; };
class trienode
{
private:
vector< trienode* > child;
bool leaf;
public:
trienode(int );
~trienode();
void initialiseChild(int i);
trienode* getChild(int i);
void setLeaf() { leaf = true; };
bool isLeaf() { return leaf; };
};
trienode::trienode(int size)
{
for(int i = 0; i < size; i++)
{
child.push_back(NULL);
}
leaf = false;
}
trienode::~trienode()
{
for(int i = 0; i < child.size(); i++)
{
delete child.at(i);
child.at(i) = NULL;
}
}
void trienode::initialiseChild(int i)
{
child.at(i) = new trienode(child.size());
}
trienode* trienode::getChild(int i)
{
return child.at(i);
}
class trie
{
private:
trienode* root;
ptr toIndex;
public:
trie(int , ptr );
~trie();
void insert(const string& ref);
bool search(const string& ref);
};
trie::trie(int size, ptr toIndex) : toIndex(toIndex), root(new trienode(size)) { }
trie::~trie()
{
cout << "In destructor trie" << endl;
delete root;
root = NULL;
}
void trie::insert(const string& ref)
{
int size = ref.size();
trienode* root = root;
for(int i = 0; i < size; i++)
{
int index = toIndex(ref[i]);
if(root->getChild(index) == NULL) // crashing in getChild()
{
root->initialiseChild(index);
}
root = root->getChild(index);
}
root->setLeaf();
}
bool trie::search(const string& ref)
{
trienode* root = root;
int size = ref.size();
for(int i = 0; i < size && root != NULL; i++)
{
int index = toIndex(ref[i]);
if((root = root->getChild(index)) == NULL)
{
break;
}
}
return (root != NULL && root->isLeaf());
}
int main(int argc,char* argv[])
{
trie* altrie = new trie(LOWERCASE_ALPHABET_SiZE, charToIndex);
int n;
string temp;
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> temp;
altrie->insert(temp);
}
int k;
for(int i = 0; i < k; i++)
{
cin >> temp;
if(altrie->search(temp))
{
cout << temp << " exists in the trie" << endl;
}
else
{
cout << temp << " doesn`t exist in the trie" << endl;
}
}
return 0;
}
I am creating Trie by supplying no of children it can have in each level and function pointer to convert the given character to index. After that I am Creating the root node of trie and when I`m inserting the first string it is getting Segmentation Fault in getChild Function
First things first explain me the reason behind the crash.
Explain me how I can improve the implementation of trie.

You are using the same name for member and local variables, like this:
trienode* root = root;
The compiler cannot tell the diffirence between the local root and trie::root so you are assigning it to itself.

Related

Having trouble printing a chained Hashtable c++

#include <iostream>
#include <list>
using namespace std;
const int TABLESIZE = 3;
class HashTable
{
public:
string k;
int v;
HashTable* next;
HashTable(string k, int v)
{
this->k = k;
this->v = v;
next = NULL;
}
};
class HashMapTable
{
private:
HashTable **t;
public:
HashMapTable()
{
t = new HashTable * [TABLESIZE];
for (int i = 0; i < TABLESIZE; i++)
{
t[i] = NULL;
}
}
int HashFunction(int v)
{
return v % TABLESIZE;
}
void Insert(string k, int v)
{
int hV = HashFunction(v);
HashTable* p = NULL;
HashTable* en = t[hV];
while (en!= NULL)
{
p = en;
en = en->next;
}
if (en == NULL)
{
en = new HashTable(k, v);
if (p == NULL)
{
t[hV] = en;
} else
{
p->next = en;
}
} else
{
en->v = v;
}
}
void PrintTable()
{
for (int i = 0; i < TABLESIZE; i++)
{
if(t[i] != NULL)
{
cout << t[i]->k << " " << t[i]->v << endl;
}
}
}
~HashMapTable()
{
for (int i = 0; i < TABLESIZE; i++)
{
if (t[i] != NULL)
delete t[i];
delete[] t;
}
}
};
int main()
{
HashMapTable HT;
cout << "entering the pairs now" << endl;
HT.Insert("Boramir", 25);
HT.Insert("Legolas", 101);
HT.Insert("Gandalf", 49);
cout << "printing the pairs now" << endl;
HT.PrintTable();
}
My issue is that not all the key value pairs in the table are being printed depending on the table size. If it's 3 (the desired amount) only 2 print, but if it's at least 7, they all print? I'm not sure what piece of my code is causing this to happen. Also, if there are multiple pairs in one bucket, the second/third/etc pair doesn't print and I'm not sure why. Thanks for any help.

relational operator overloading not working in C++

I am trying to implement Huffman encoding in C++ using custom made priority_queue. I am storing the information in structure named Node. Here is the code
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
//two same name functions are for min heap and max heap(Function overloading)
struct Node{
char letter;
int value;
Node* left;
Node* right;
Node(char letter,int value, Node* left,Node* right){
this->letter = letter;
this->value = value;
this->left = left;
this->right = right;
}
bool operator < (const Node* &a){//HERE IS THE PROBLEM
if((this->value) < (a->value))
return true;
else
return false;
}
bool operator > (const Node* &a){//HERE IS THE PROBLEM
if((this->value) > (a->value))
return true;
else
return false;
}
};
template <class T>
class Priority_Queue{
public:
int k;
int sz;
vector<T> v;
Priority_Queue(int k){
sz = 0;
this->k = k;
}
void heapify(int index,int n){
int max_index = index;
for(int i = index*k+1;i <= min(n-1,index*k+k);++i){
if(v[i] > v[max_index])
max_index = i;
}
if(index != max_index){
swap(v[max_index],v[index]);
heapify(v,max_index,n);
}
}
void heapify(vector<int> &v,int index,int n,bool trigger){
//for calling min_heapify using function overloading
int min_index = index;
for(int i = index*k+1;i <= min(n-1,index*k+k);++i){
if(v[i] < v[min_index])
min_index = i;
}
if(index != min_index){
swap(v[min_index],v[index]);
heapify(v,min_index,n,trigger);
}
}
void Insert(T val){
if(sz == (int)v.size()){
v.push_back(val);
++sz;
}
else
v[sz++] = val;
int parent = (sz-1)/k;
int node = sz-1;
while(node >= 1){
int parent = (node-1)/k;
if(v[parent] < v[node]){
swap(v[parent],v[node]);
node = parent;
parent = (parent-1)/k;
}
else
break;
}
}
void Insert(T val, bool trigger){
if(sz == (int)v.size()){
v.push_back(val);
++sz;
}
else
v[sz++] = val;
int parent = (sz-1)/k;
int node = sz-1;
while(node >= 1){
int parent = (node-1)/k;
if(v[parent] > v[node]){// IF CONDITION DOESN'T WORK
swap(v[parent],v[node]);
node = parent;
parent = (parent-1)/k;
}
else
break;
}
}
void Pop(){
if(sz == 0){
cout << "Heap Underflow\n";
return;
}
swap(v[0],v[sz-1]);
--sz;
heapify(0,sz);
}
void Pop(bool trigger){
if(sz == 0){
cout << "Heap Underflow\n";
return;
}
swap(v[0],v[sz-1]);
--sz;
heapify(0,sz,trigger);
}
T Top(){
return v[0];
}
void printHeap(){
for(int i = 0; i < sz;++i){
cout << v[i]->value << " ";
}
cout << "\n";
}
};
int main()
{
string s;
cin >> s;
int n = s.length();
vector<int> freq(26,0);
for(int i = 0; i < n;++i){
++freq[s[i]-'a'];
}
Priority_Queue<Node*> pq(2);
for(int i = 0; i < 26;++i){
if(freq[i] == 0)
continue;
pq.Insert(new Node(char(i+'a'),freq[i],NULL,NULL),true);
}
pq.printHeap();
}
I don't have much experience with C++ and I am having trouble overloading relational operators where I want to compare two structure pointers based on the value parameter.For example: if I enter aab , the if condition in Insert function should be executed but it never happens. I searched up a lot regarding overloading of relational operators but none of them seem to fix the issue I am facing. Can someone please help me ? What am I doing wrong while overloading the operator?
You probably should make your method look like this:
bool operator<(const Node &node) const {
return value < node.value;
}
Notice the slightly different method signature. And then you should test it with an absolutely minimal method.
int main(int, char **) {
Node first{'a', 10, nullptr, nullptr};
Node second{'b', 5, nullptr, nullptr};
cout << "first < second: " << (first < second) << endl;
cout << "second < first: " << (second < first) << endl;
}
In your code, you might have to do this:
if (*v[index] < *v[otherIndex)
Another comment: don't name variables like v. That's going to bite you in the backside as your programs get bigger. Give them longer names that are more searchable and descriptive. vec is better than v.

how to fix my implementation of Auto-complete feature using Trie Tree?

Hi so i've been trying to implement Auto-complete/suggestion using trie tree
but the suggestion part only suggests 1 or 2 first similar words to it and i can't find out what causing this.
This is my Trie structre
struct TrieNode {
struct TrieNode* children[ALPHABET_SIZE];
bool isEndOfWord;
};
struct TrieNode* getNode(void) {
struct TrieNode* pNode = new TrieNode;
pNode->isEndOfWord = false;
for (int i = 0; i < ALPHABET_SIZE; i++)
pNode->children[i] = NULL;
return pNode;
}
bool isLeafNode(struct TrieNode* root) { return root->isEndOfWord != false; }
and this is the suggestion/Auto-complete part
void suggestionsRec(struct TrieNode* root, string currPrefix) {
if (root->isEndOfWord) {
cout << currPrefix;
cout << endl;
}
if (isLeafNode(root))
return;
for (int i = 0; i < ALPHABET_SIZE; i++)
{
if (root->children[i])
{
currPrefix.push_back(97 + i);
suggestionsRec(root->children[i], currPrefix);
currPrefix.pop_back();
}
}
}
int spellchecker(TrieNode* root, const string query) {
struct TrieNode* pCrawl = root;
int level;
int n = query.length();
for (level = 0; level < n; level++) {
int index = CHAR_TO_INDEX(query[level]);
if (!pCrawl->children[index])
return 0;
pCrawl = pCrawl->children[index];
}
bool isWord = (pCrawl->isEndOfWord == true);
bool isLast = isLeafNode(pCrawl);
if (isWord && isLast) {
cout << query << endl;
return -1;
}
if (!isLast) {
string prefix = query;
suggestionsRec(pCrawl, prefix);
return 1;
}
}
for example when i try words like : [ the , there , these ] and input is "t" all it suggests is "the" .
this is the whole code https://pastebin.com/VPd94rny
also any suggestion to improve my code is much appreciated

Trie C++ Strings not completely filling all the values in a text file

i'm trying to sort a large amount of strings alphabetically and by length and it seems i'm only sorting around 1/7 of the amount needed. I am trying to sort around 100,000 words, when I sorted 70000 I ended up with 8000 words sorted and can't seem to find why it isn't working. Any help would be much appreciated
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
class Node
{
public:
char value; // the character value
bool end; // indicates whether this node completes a word
Node * children[93]; // represents the 93 ascii values for 33-126
Node(char newChar);
~Node();
};
class Trie
{
public:
Trie();
~Trie();
void addWord(string word);
Node * getRoot();
private:
Node * root;
};
Node::Node(char newChar)
{
value = newChar;
for (int i = 0; i < 93; ++i)
children[i] = NULL;
}
Node::~Node()
{
delete[] children;
}
Trie::Trie()
{
root = new Node(' ');
root->end = true;
}
Trie::~Trie()
{
delete root;
}
Node * Trie::getRoot()
{
return root;
}
void Trie::addWord(string word)
{
Node * currentNode = root;
for (int i = 0; i < word.size(); ++i)
{
char currentChar = word.at(i);
int index = currentChar - '!';
if (currentNode->children[index] != NULL)
{
currentNode = currentNode->children[index];
}
else
{
Node * newNode = new Node(currentChar);
currentNode->children[index] = newNode;
currentNode = newNode;
}
if (i == word.size() - 1)
{
currentNode->end = true;
}
}
}
void alphabetize(Node * node, vector<string> & sorting, string prefix = "") //why dont i have to declare this?
{
if (node->end)
{
sorting.push_back(prefix);
}
for (int i = 0; i < 93; ++i)
{
if (node->children[i] != NULL)
{
string currentString = prefix + node->children[i]->value; //store all characters
alphabetize(node->children[i], sorting, currentString);
}
else
{
}
}
}
int main()
{
Trie * t = new Trie();
string tempS;
int lengthCounter = 0;
ifstream fin;
fin.open("test.txt");
vector< vector<string> > sortLength;
vector <string> row(0, "");
vector<string> sorted;
while(fin >> tempS)
{
while(tempS.length() > lengthCounter)
{
sortLength.push_back(row);
lengthCounter++;
}
t->addWord(tempS);
}
alphabetize(t->getRoot(),sorted); //filled with sorted vector
for(int i = 0; i < sorted.size(); i++)
{
sortLength[sorted[i].length()-1].push_back(sorted[i]);
}
for(int k = 0; k < sortLength.size(); k++)
{
for(int l = 0; l < sortLength[k].size(); l++)
{
cout << sortLength[k][l] << "\n";
}
}
cout << sorted.size();
return 0;
}

user defined hash table with value as function pointer

Below is my code
to create hashtable with key as Char* and value as Function pointer
// hash1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#define SIZE_KEY 16
#define SIZE_VALUE1 64
#define SIZE_VALUE2 16
#define DEFAULT_TABLESIZE 101
using namespace std;
typedef void (*FunctionPtr)();
typedef void (*FunctionPtr1)();
void (*FunctionPtr2)();
void ping(){
cout<<"hello";
}
void refresh(){
cout<<"refresh";
}
typedef struct NODE
{
NODE(char* Key1,FunctionPtr func_ptr)
{
strcpy_s(Key,Key1);
FunctionPtr1 func_ptr1;
func_ptr1=func_ptr;
next = NULL;
}
NODE(){
}
char Key[SIZE_KEY];
FunctionPtr1 func_ptr1[SIZE_VALUE1];
NODE *next;
};
class Hashtable
{
private:
int table_size;
NODE** table;
int size;
long hashString(char* Key);
NODE* find(char* Key);
NODE* current_entry;
public:
int current_index;
Hashtable(int T = DEFAULT_TABLESIZE);//constructor
virtual ~Hashtable();//destructor
bool put(NODE *);
bool get(NODE *);
bool contains(char* Key);
void removeAll();
int getSize();
void initIterator();
bool hasNext();
void getNextKey(char* Key);
friend void disp(NODE *);
};
Hashtable::Hashtable(int T)
{
size = 0;
table_size = T;
table = new NODE*[table_size];
for(int i=0; i<table_size; i++)
{
table[i] = NULL;
}
}
Hashtable::~Hashtable()
{
removeAll();
delete[] table;
}
bool Hashtable::put(NODE *N)
{//start put
if(find(N->Key) != NULL)
{
return false;
}
//NODE* entry = new NODE( N->Key ,*(FunctionPtr *)N->func_ptr1 );
NODE* entry = new NODE( N->Key ,*(FunctionPtr *)N->func_ptr1 );
int bucket = hashString(N->Key);
entry->next = table[bucket];
table[bucket] = entry;
size++;
return true;
}//end put
bool Hashtable::get(NODE* N)
{//start get
NODE* temp = find(N->Key);
if(temp == NULL)
{
*(FunctionPtr *)N->func_ptr1 = refresh;
return false;
}
else
{
*(FunctionPtr *)N->func_ptr1= *(FunctionPtr *)temp->func_ptr1;
return true;
}
}//end get
bool Hashtable::contains(char* Key)
{//start contains
if(find(Key) == NULL)
{
return false;
}
else
{
return true;
}
}//end contains
void Hashtable::removeAll()
{//start removeAll
for(int i=0; i<table_size; i++)
{
NODE* temp = table[i];
while(temp != NULL)
{
NODE* next = temp->next;
disp(temp);
delete temp;
temp = next;
}
}
size = 0;
}//end removeAll
int Hashtable::getSize()
{
return size;
}
NODE* Hashtable::find(char* Key)
{ //start find
int bucket = hashString(Key);
NODE* temp = table[bucket];
while(temp != NULL)
{
if(strcmp(Key, temp->Key) == 0)
{
return temp;
}
temp = temp->next;
}
return NULL;
}//end find
long Hashtable::hashString(char* Key)
{//start hashString
int n = strlen(Key);
long h = 0;
for(int i=0; i<n; i++)
{
//To get almost fair distributions of NODEs over the array
h = (h << 3) ^ Key[i];
}
return abs(h % table_size );
}//end hashString
void Hashtable::initIterator()
{//start initIterator
current_entry = NULL;
current_index = table_size;
for(int i=0; i<table_size; i++)
{
if(table[i] == NULL)
{
continue;
}
else
{
current_entry = table[i];
current_index = i;
break;
}
}
}//end initIterator
bool Hashtable::hasNext()
{
if(current_entry == NULL)
{
return false;
}
else
{
return true;
}
}
void Hashtable::getNextKey(char* Key)
{
if(current_entry == NULL)
{
Key[0] = '\0';
return;
}
strcpy(Key, current_entry->Key);
if(current_entry->next != NULL)
{
current_entry = current_entry->next;
}
else
{
for(int i=current_index+1; i<table_size; i++)
{
if(table[i] == NULL)
{
continue;
}
current_entry = table[i];
current_index = i;
return;
}
current_entry = NULL;
current_index = table_size;
}
}
void dispAll(Hashtable* hashtable);
int main()
{
char temp1[SIZE_KEY];
Hashtable* hashtable = new Hashtable();
NODE N1("1",ping);
if(!hashtable->contains(N1.Key))
{
cout << "\nAdding NODE: ";
disp(&N1);
hashtable->put(&N1);
}
// dispAll(hashtable);
strcpy(N1.Key, "314");
*(FunctionPtr *) N1.func_ptr1=refresh;
if(!hashtable->contains(N1.Key))
{
cout << "\nAdding NODE: ";
disp(&N1);
hashtable->put(&N1);
}
/* strcpy(N1.Key, "320");
*(FunctionPtr *) N1.func_ptr1= ping;
if(!hashtable->contains(N1.Key))
{
cout << "\nAdding NODE: ";
disp(&N1);
hashtable->put(&N1);
}
strcpy(N1.Key, "768");
*(FunctionPtr *)N1.func_ptr1= refresh;
if(!hashtable->contains(N1.Key))
{
cout << "\nAdding node: ";
disp(&N1);
hashtable->put(&N1);
}
strcpy(N1.Key, "756");
*(FunctionPtr *) N1.func_ptr1= refresh;
if(!hashtable->contains(N1.Key))
{
cout << "\nAdding node: ";
disp(&N1);
hashtable->put(&N1);
} */
dispAll(hashtable);
// strcpy(temp1,"314");
// hashtable->remove(temp1);
// cout << "\n\nAfter removing 314:" << endl;
// dispAll(hashtable);
cout << "\n\nDestroying hashtable:" << endl;
delete hashtable;
return 0;
}
void disp(NODE *N1)
{
cout << "\nKey: " << N1->Key << "\nFunction "
<< N1->func_ptr1 << endl;
// FunctionPtr2();
}
void dispAll(Hashtable *hashtable)
{
NODE N1;
cout << "\n\nCurrent nodes in hashtable:" << endl;
hashtable->initIterator();
while(hashtable->hasNext())
{
//cout<<"Current Index === "<<hashtable->current_index;
hashtable->getNextKey(N1.Key);
hashtable->get(&N1);
disp(&N1);
}
}
each time data is written in hash table VALUE cointains the same address :(
i want address of particular function that i will send..
Some of the problems may be in struct NODE.
typedef struct NODE
{
NODE(char* Key1,FunctionPtr func_ptr)
{
strcpy_s(Key,Key1);
FunctionPtr1 func_ptr1; // <-- Problem may be here
func_ptr1=func_ptr;
next = NULL;
}
NODE(){
}
char Key[SIZE_KEY];
FunctionPtr1 func_ptr1[SIZE_VALUE1]; // <-- And here
NODE *next;
};
You declared a local func_ptr1 in NODE::NODE(char*, FunctionPtr), and assign the parameter func_ptr to func_ptr1. Thus, func_ptr is assigned to a local variable, not a member variable. And, once the constructor returns, nothing about the function pointer is remembered.
Another problem: why is NODE::func_ptr1 an array of FunctionPtr1? I don't think you intended to store multiple function pointers in one NODE instance.