Why this code failed to run - c++

i want to generate a tree of siblings as under
ABCD
/ | \ \
A B C D
ABCD has four nodes i have taken a array for this *next[]. but this code does not run successfully but it produces the sequence. i have written code in main() which provide characters to the enque function. e.g. str.at(x) where x is variable in for loop.
struct node
{
string info;
struct node *next[];
}*root,*child;
string str, goal;
int dept=0,bnod=0,cl,z=0;
void enqueue(string n);
void enqueue(string n)
{
node *p, *temp;
p=new node[sizeof(str.length())];
p->info=n;
for (int x=0;x<str.length();x++)
p->next[x]=NULL;
if(root==NULL)
{
root=p;
child=p;
}
else
{
cout<<" cl="<<cl<<endl;
if(cl<str.length())
{
child->next[cl]=p;
temp=child->next[cl];
cout<<"chile-info "<<temp->info<<endl;
}
else
cout<<" clif="<<cl<<endl;
}
}
OUTPUT
Enter String: sham
cl=0
chile-info s
cl=1
chile-info h
cl=2
chile-info a
cl=3
chile-info m
RUN FAILED (exit value 1, total time: 2s)

Firstly, where does "RUN FAILED" come from? Is that specific to your compiler?
Secondly, about the line p=new node[sizeof(str.length())];, it probably won't give you what you wanted because you're taking the sizeof of an unsigned integer ( which, depending on your platform is likely to give you 4 regardless of the string length. Which is not what you're after - you want the actual length of the string ).
So - since you're already using std::string, why not use std::vector? Your code would look a lot friendlier :-)
If I take the first couple of lines as your desired output ( sorry, the code you posted is very hard to decipher, and I don't think it compiles either, so I'm ignoring it ;-) )
Would something like this work better for you?
#include <iostream>
#include <vector>
#include <string>
typedef struct node
{
std::string info;
std::vector<struct node*> children;
}Node;
Node * enqueue(std::string str)
{
Node * root;
root = new Node();
root->info = str;
for (int x = 0; x < str.length(); x++)
{
Node * temp = new Node();
temp->info = str[x];
root->children.push_back(temp);
}
return root;
}
int main()
{
Node * myRoot = enqueue("ABCD");
std::cout << myRoot->info << "\n";
for( int i = 0; i < myRoot->children.size(); i++)
{
std::cout << myRoot->children[i]->info << ", ";
}
char c;
std::cin >> c;
return 0;
}

Your code seems not full.
At least the line
p=new node[sizeof(str.length())];
seems wrong.
I guess enqueue should be something similar to the following:
struct node
{
string info;
struct node *next; // [] - is not necessary here
}*root,*child;
string str, goal;
int dept=0,bnod=0,cl,z=0;
void enqueue(string n)
{
node *p, *temp;
p = new node;
p->next = new node[str.length()];
p->info=n;
for (int x=0;x<str.length();x++)
{
p->next[x] = new node;
p->next[x]->next = 0;
p->next[x]->info = str[x];
}
if(root==NULL)
{
root=p;
child=p;
}
}
Please provide more info to give a more correct answer

Related

Null Pointer Error after generating huffman code using recursive call to a function but it is not keeping the NULL value

I was trying to generate huffman code for the input:
testcases=1
string s=abcdef
frequency={5 , 9 ,12 ,13 , 16, 45}
I was trying to traverse through pointers.
I am not sure if there is some error in copying the struct containing pointers because on printing the string it works fine for the nodes containing {12 and 13}
But it does not go back to the next node once it gets to node 5
// { Driver Code Starts
#include<bits/stdc++.h>
using namespace std;
// } Driver Code Ends
struct Node{
int index,frequency;
Node *left,*right;
};
struct comp{
bool operator()(Node const &a,Node const &b){
if(a.frequency == b.frequency)
return a.index > b.index;
return a.frequency > b.frequency;
}
};
class Solution
{
vector<Node> tree;
public:
void give_me_codes(Node *root,vector<string> &ans,string s,int &size){
cout<<"Printing s to show call: "<<s<<'\n';
/*while(root!=NULL){
cout<<root->index<<" "<<root->frequency<<"\n";
root=root->right;
root=root->left;
}*/
if(root==NULL){
return;
}
if(root->index<size)
ans.push_back(s);
if(root->left!=NULL)give_me_codes(root->left, ans,s+"0",size);
if(root->right!=NULL)give_me_codes(root->right,ans,s+"1",size);
}
vector<string> huffmanCodes(string S,vector<int> f,int N)
{
// Code here
priority_queue<Node, vector<Node>, comp> heap;
for(int i=0;i<N;++i){
Node element={.index=i,.frequency=f[i],.left=NULL,.right=NULL};
heap.push(element);
}
int sz = heap.size();
/*for(int i=0;i<sz;++i){
Node ele = heap.top();
heap.pop();
cout<<ele.index<<" "<<ele.frequency<<"\n";
}*/
Node *root;
int i=0;
while(heap.size()>1){
Node l = heap.top();heap.pop();
Node r =heap.top();heap.pop();
tree.push_back(l);
tree.push_back(r);
Node _new = {.index=sz++,.frequency=l.frequency+r.frequency,.left=&tree[i++],.right=&tree[i++]};
root =&_new;
heap.push(_new);
}
//cout<<tree[4].left<<" "<<tree[4].frequency<<'\n';
//cout<<tree[2].left<<" "<<tree[2].frequency<<'\n';
//tree[0].left=tree[0].right=NULL;
//tree[1].left=tree[1].left=NULL;
tree.push_back(*root);
vector<string> ans;
give_me_codes(root,ans,"",N);
cout<<'\n';
vector<string> v(N,"A");
return ans;
}
};
// { Driver Code Starts.
int main(){
int T;
cin >> T;
while(T--)
{
string S;
cin >> S;
int N = S.length();
vector<int> f(N);
for(int i=0;i<N;i++){
cin>>f[i];
}
Solution ob;
vector<string> ans = ob.huffmanCodes(S,f,N);
for(auto i: ans)
cout << i << " ";
cout << "\n";
}
return 0;
} // } Driver Code Ends
I tried assiging the left and right pointers of node 5 to NULL but it doesn't makes any difference and the output (when I print string s) stops after printing 110000 although I am expecting it to print 1100 and then probably move to the next node.
I shared the whole code and you can see what the output is showing. Can anyone please explain what is wrong here and what could be the possible fix?

Pouring via Depth First Search node linking to itself. C++

Working on a program to solve the pouring problem:
I believe I am down to one last issue. My data structure is as follows:
I have an vector of Node pointers and each node contains a int array, and an address to the next node. In testing everything functions properly. The goal of this data structure is to basically function as an adjacency list. Where each node is linked to the nodes that it would have an edge to.
Currently my problem is when I am attempting to link these nodes to one another:
the LinkState function that I have should accomplish this, however it is instead resulting in the program running...forever.
The function should simply iterate through the individual nodes linked list and find where to connect the new node. Instead it is causing a node to constantly be leak to itself..which is leading to the runtime issue.
Sorry if this is a bit confusing. Any help would be greatly appreciated.
p.s. I know there are better ways to solve this problem like BFS, I'd like to stick to DFS.
#ifndef _POURINGLIST_H_
#define _POURINGLIST_H_
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
struct Node{
int state[3];
Node* next = NULL;
};
class PouringList{
Node* init;
vector<Node*> Head;
int max[3];
int steps;
public:
PouringList(){
//max values for comaprison
max[0] = 10;
max[1] = 7;
max[2] = 4;
//init values to begin DFS
init = new Node;
init->state[0] = 0;
init->state[1] = 7;
init->state[2] = 4;
};
//private methods not to be called by user
private:
//pours some good old h2o
Node pour(Node* curr_state, int A, int B){
int a = curr_state->state[A];
int b = curr_state->state[B];
int change = min(a, max[B]-b);
Node newState = *curr_state;
newState.state[A] = (a-=change);
newState.state[B] = (b+=change);
return newState;
}
//O(n) complexity used to check if a node is already in head
bool isIn(Node* find_me){
for(vector<Node*>::iterator i = Head.begin(); i != Head.end(); i++) {
if (equal(begin(find_me->state), end(find_me->state), begin((*i)->state)))
return true;
}
return false;
}
void printNode(Node* print){
for(int i = 0; i < 3; i++){
cout << print->state[i] << " ";
}
cout << endl;
}
int locate(Node* find_me){
for(vector<Node*>::iterator i = Head.begin(); i != Head.end(); i++) {
if (equal(begin(find_me->state), end(find_me->state), begin((*i)->state)))
return distance(Head.begin(), i);
}
return -1;
}
void LinkState(Node* head, Node * nxt){
Node* vert = Head[locate(head)];
while(vert->next != NULL){
vert = vert->next;
}
vert->next = nxt;
}
public:
void DFS(){
steps = 0;
//start exploring at initial value
explore(init);
}
void explore(Node* vertex){
//base case to end
if(!isIn(vertex)){
Head.push_back(vertex);
if(vertex->state[1] == 2 || vertex->state[2] == 2){
cout << steps << endl;
printNode(vertex);
return;
}
//generate all possible states and connects them to Head vertex
else{
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
Node conn1 = pour(vertex,i,j);
Node *conn = &conn1;
if(i!=j && !isIn(conn)){
cout << i << " adds water to " << j << endl;
LinkState(vertex, conn);
}
}
}
}
Node* Nextex = vertex;
//printNode(vertex);
while(Nextex != NULL){
//new neighbor
if(!isIn(Nextex)){
//printNode(Nextex);
explore(Nextex);
}
Nextex = Nextex->next;
}
}
//printNode(Nextex);
else{
cout <<"Dead end" << endl;
}
}
//start from init node and show path to solution
void display(){
Node *output;
for(int i = 0; i < Head.size(); i++){
output = Head[i];
while ( output != NULL){
printNode(output);
output = output->next;
}
cout << '#' <<endl;
}
}
};
#endif // _POURINGLIST_
basic driver:
#include "PouringList.h"
int main(){
PouringList s1;
s1.DFS();
}
Edit
I've attempted the suggested fix before (This is what I'm assuming you mean). It still lead to the programming running forever. Also I do not know enough about smartpointers to go and overhaul the application!
Node conn1 = pour(vertex,i,
Node *conn = new Node;
conn = &conn1;
You are storing the address of a local variable in your list.
In explore, you have
Node conn1 = pour(vertex,i,j);
Node *conn = &conn1;
then later pass conn to LinkState, which stores that pointer in your PouringList. All your added nodes will point at the same memory address.
What you should be doing is allocating a new Node and using that (preferably using some sort of smart pointer rather than storing raw pointers so the clean up will happen automatically).

SIGSEGV error occurs in implementation of a hash table in C++

I am trying to implement a hash table data structure in C++, but every time i run the program i get a run time error(SIGSEGV, segmentation fault) in line number 86 like here.
i.e.: putInHash(str,hashTable,m); in main().
This is my code:
#include <iostream>
#include<string.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
typedef struct node
{
struct node *next,*prev;
string data;
}node;
int hashCode(string str)
{
char arr[str.size()+1];
strcpy(arr,str.c_str());
int code=0;
for(int i=0;i<str.size();i++)
{
code+=((i+1)*((int)arr[i]));
}
return code;
}
int compress(int k,int m)
{
double a=(sqrt(5.0)-1)/2;
return floor(m*(fmod(k*a,1)));
}
void display(node* hashTable[],int m)
{
for(int i=0;i<m;i++)
{
cout<<i<<":\n";
node* p=hashTable[i];
while(p!=NULL)
{
cout<<p->data<<" , ";
}
cout<<"\n";
}
}
void putInHash(string str,node* hashTable[],int m)
{
int k=hashCode(str);
int bucket=compress(k,m);
if(hashTable[bucket]==NULL)
{
hashTable[bucket]=(node*)malloc(sizeof(node));
hashTable[bucket]->prev=NULL;
hashTable[bucket]->next=NULL;
hashTable[bucket]->data=str;
}
else
{
node* temp=(node*)malloc(sizeof(node));
temp->data=str;
temp->next=hashTable[bucket];
hashTable[bucket]->prev=temp;
temp->prev=NULL;
hashTable[bucket]=temp;
}
}
int main()
{
cout<<"Enter number of strings to add in hash table: ";
long int n;
cin>>n;
cout<<"\n";
int m=13;
node* hashTable[m];
for(int i=0;i<m;i++)
{
hashTable[i]=NULL;
}
string str;
cout<<"Enter the strings:\n";
for(int i=0;i<n;i++)
{
cin>>str;
putInHash(str,hashTable,m);
}
display(hashTable,m);
return 0;
}
I thought it might be due to passing the string, but it turned out this wasn't the case.
Can somebody please guide me through it.
I think the error may be in passing the hashTable[] as an argument.
I can't reproduce your problem (I'm using clang++ in a Linux platform and I suppose that your problem is platform dependent) but I see something that can explain it.
You use malloc() to allocate memory for a struct with a std::string in it.
This is bad.
Really, really bad.
Because malloc() can allocate the memory but can't construct the data member in it.
In C++ you should use new; at least, allocating not trivial objects (std::string isn't trivial).
// node* temp=(node*)malloc(sizeof(node)); // DANGEROUS
node * temp = new node;
This is the problem that cause the sigsegv (I suppose) but your code has a lot of other problem.
Example: the while in display() goes in loop because p remain unchanged; you should change display() in this way
void display (node * hashTable[], int m)
{
node * p;
for(int i=0;i<m;i++)
{
cout << i << ":\n";
for ( p = hashTable[i] ; p ; p = p->next )
cout << p->data << " , ";
cout << "\n";
}
}
Another important point: variable length arrays isn't C++; it's C (C99). So this lines are wrong
char arr[str.size()+1];
node* hashTable[m];
You don't need the first (absolutely useless) and you can simplify hashcode() in this way (and please, pass the strings by const reference, when possible)
int hashCode (const string & str)
{
int code = 0;
for ( int i = 0 ; i < str.size() ; ++i )
code += (i+1) * int(str[i]);
return code;
}
About hashTable, you can substitute it with a std::vector
// node* hashTable[m]; no C++
//for(int i=0;i<m;i++) // useless
//{ // useless
// hashTable[i]=NULL; // useless
//} // useless
std::vector<node *> hashTable(m, NULL); // m NULL node pointers
Obviously, putInHash() should be
void putInHash (string str, std::vector<node*> & hashTable, int m)
and display()
void display (const std::vector<node*> & hashTable, int m)
And remember to free the allocated memory.
p.s.: sorry for my bad English.
--- EDIT ---
phonetagger is right: deleting the memory (a vector o linked nodes) isn't trivial.
I suggest a function like the following
void recursiveFreeNode (node * & nd)
{
if ( nd )
{
recursiveFreeNode(nd->next);
delete nd; // added with EDIT 2; sorry
nd = NULL; // useless, in this, case, but good practice
}
}
and call it (for every node of the vector) in main(), after display() calling
for ( unsigned ui = 0U ; ui < hashTable.size() ; ++ui )
recursiveFreeNode(hashTable[ui]);
--- EDIT 2 ---
Sorry: I've forgot the more important line: delete node (thanks phonetagger).
Following the other suggestion of phonetagger, I propose a not-recursive function for deleting the hashtable's node
void loopFreeNode (node * & nd)
{
node * tmp;
for ( ; nd ; nd = tmp )
{
tmp = nd->next;
delete nd;
}
nd = NULL;
}
Obviously the for loop, to use loopFreeNode(), should be
for ( unsigned ui = 0U ; ui < hashTable.size() ; ++ui )
loopFreeNode(hashTable[ui]);

Hash table implementation in C++

I am trying the following code for Hash table implementation in C++. The program compiles and accepts input and then a popup appears saying " the project has stopped working and windows is checking for a solution to the problem. I feel the program is going in the infinite loop somewhere. Can anyone spot the mistake?? Please help!
#include <iostream>
#include <stdlib.h>
#include <string>
#include <sstream>
using namespace std;
/* Definitions as shown */
typedef struct CellType* Position;
typedef int ElementType;
struct CellType{
ElementType value;
Position next;
};
/* *** Implements a List ADT with necessary functions.
You may make use of these functions (need not use all) to implement your HashTable ADT */
class List{
private:
Position listHead;
int count;
public:
//Initializes the number of nodes in the list
void setCount(int num){
count = num;
}
//Creates an empty list
void makeEmptyList(){
listHead = new CellType;
listHead->next = NULL;
}
//Inserts an element after Position p
int insertList(ElementType data, Position p){
Position temp;
temp = p->next;
p->next = new CellType;
p->next->next = temp;
p->next->value = data;
return ++count;
}
//Returns pointer to the last node
Position end(){
Position p;
p = listHead;
while (p->next != NULL){
p = p->next;
}
return p;
}
//Returns number of elements in the list
int getCount(){
return count;
}
};
class HashTable{
private:
List bucket[10];
int bucketIndex;
int numElemBucket;
Position posInsert;
string collision;
bool reportCol; //Helps to print a NO for no collisions
public:
HashTable(){ //constructor
int i;
for (i=0;i<10;i++){
bucket[i].setCount(0);
}
collision = "";
reportCol = false;
}
int insert(int data){
bucketIndex=data%10;
int col;
if(posInsert->next==NULL)
bucket[bucketIndex].insertList(data,posInsert);
else { while(posInsert->next != NULL){
posInsert=posInsert->next;
}
bucket[bucketIndex].insertList(data,posInsert);
reportCol=true;}
if (reportCol==true) col=1;
else col=0;
numElemBucket++;
return col ;
/*code to insert data into
hash table and report collision*/
}
void listCollision(int pos){
cout<< "("<< pos<< "," << bucketIndex << "," << numElemBucket << ")"; /*codeto generate a properly formatted
string to report multiple collisions*/
}
void printCollision();
};
int main(){
HashTable ht;
int i, data;
for (i=0;i<10;i++){
cin>>data;
int abc= ht.insert(data);
if(abc==1){
ht.listCollision(i);/* code to call insert function of HashTable ADT and if there is a collision, use listCollision to generate the list of collisions*/
}
//Prints the concatenated collision list
ht.printCollision();
}}
void HashTable::printCollision(){
if (reportCol == false)
cout <<"NO";
else
cout<<collision;
}
The output of the program is the point where there is a collision in the hash table, thecorresponding bucket number and the number of elements in that bucket.
After trying dubbuging, I come to know that, while calling a constructor you are not emptying the bucket[bucketIndex].
So your Hash Table constructor should be as follow:
HashTable(){ //constructor
int i;
for (i=0;i<10;i++){
bucket[i].setCount(0);
bucket[i].makeEmptyList(); //here we clear for first use
}
collision = "";
reportCol = false;
}
//Creates an empty list
void makeEmptyList(){
listHead = new CellType;
listHead->next = NULL;
}
what you can do is you can get posInsert using
bucket[bucketIndex].end()
so that posInsert-> is defined
and there is no need to
while(posInsert->next != NULL){
posInsert=posInsert->next;
because end() function is doing just that so use end() function

Trie Implementation in C++

I am trying to implement the trie as shown on the TopCoder page. I am modifying it a bit to store the phone numbers of the users. I am getting segmentation fault. Can some one please point out the error.
#include<iostream>
#include<stdlib.h>
using namespace std;
struct node{
int words;
int prefix;
long phone;
struct node* children[26];
};
struct node* initialize(struct node* root) {
root = new (struct node);
for(int i=0;i<26;i++){
root->children[i] = NULL;
}
root->word = 0;
root->prefix = 0;
return root;
}
int getIndex(char l) {
if(l>='A' && l<='Z'){
return l-'A';
}else if(l>='a' && l<='z'){
return l-'a';
}
}
void add(struct node* root, char * name, int data) {
if(*(name)== '\0') {
root->words = root->words+1;
root->phone = data;
} else {
root->prefix = root->prefix + 1;
char ch = *name;
int index = getIndex(ch);
if(root->children[ch]==NULL) {
struct node* temp = NULL;
root->children[ch] = initialize(temp);
}
add(root->children[ch],name++, data);
}
}
int main(){
struct node* root = NULL;
root = initialize(root);
add(root,(char *)"test",1111111111);
add(root,(char *)"teser",2222222222);
cout<<root->prefix<<endl;
return 0;
}
Added a new function after making suggested changes:
void getPhone(struct node* root, char* name){
while(*(name) != '\0' || root!=NULL) {
char ch = *name;
int index = getIndex(ch);
root = root->children[ch];
++name;
}
if(*(name) == '\0'){
cout<<root->phone<<endl;
}
}
Change this:
add(root->children[ch], name++, data);
// ---------------------^^^^^^
To this:
add(root->children[ch], ++name, data);
// ---------------------^^^^^^
The remainder of the issues in this code I leave to you, but that is the cause of your run up call-stack.
EDIT OP ask for further analysis, and while I normally don't do so, this was a fairly simple application on which to expand.
This is done in several places:
int index = getIndex(ch);
root = root->children[ch];
... etc. continue using ch instead of index
It begs the question: "Why did we just ask for an index that we promptly ignore and use the char anyway?" This is done in add() and getPhone(). You should use index after computing it for all peeks inside children[] arrays.
Also, the initialize() function needs to be either revamped or outright thrown out in favor of a constructor-based solution, where that code truly belongs. Finally, if this trie is supposed to be tracking usage counts of words generated and prefixes each level is participating in, I'm not clear why you need both words and prefix counters, but in either case to update the counters your recursive decent in add() should bump them up on the back-recurse.