I am implementing Graph for the first time and for that I took this problem from SPOJ.
Took help of geeksforgeeks, applied union find algorithm to find out whether or not graph contains a cycle but I get run time error (SIGSEGV).
Can you please help why is it so?
#include<iostream>
#include<stdlib.h>
#include<string.h>
using namespace std;
struct Edge{
int s,d;
};
struct Graph{
int v,e;
struct Edge* edge;
};
struct Graph* create(int v, int e){
struct Graph* graph=(struct Graph*)malloc(sizeof (struct Graph));
graph->v=v;
graph->e=e;
graph->edge=(struct Edge*)malloc(sizeof (struct Edge));
return graph;
};
int Find(int p[],int i)
{
if (p[i] == -1)
return i;
return Find(p, p[i]);
}
void Union(int p[],int i, int j)
{
p[j]=i;
}
bool CheckCycle(struct Graph* graph)
{
int *p=(int*)malloc(graph->v* sizeof (int));
memset(p,-1,graph->v * sizeof (int));
/*for(int i=0;i<graph->v;i++)
cout<<"p"<<i<<"="<<p[i];
cout<<"\n";*/
for(int i=0;i<graph->e;i++)
{
/*cout<<"edge"<<i<<" src="<<graph->edge[i].s<<"\n";
cout<<"edge"<<i<<" dest="<<graph->edge[i].d<<"\n";*/
int x=Find(p,graph->edge[i].s);
int y=Find(p,graph->edge[i].d);
/*cout<<"x="<<x<<" "<<"y="<<y<<"\n";*/
if(x==y)
return true;
Union(p,x,y);
}
return false;
}
int main()
{
ios_base::sync_with_stdio(false);
int N,M,v1,v2;
cin>>N>>M;
if(M!=(N-1))
cout<<"NO\n";
else{
struct Graph* graph=create(N,M);
for(int i=0;i<M;i++)
{
cin>>v1;
graph->edge[i].s=v1-1;
cin>>v2;
graph->edge[i].d=v2-1;
}
if(CheckCycle(graph))
cout<<"NO\n";
else
cout<<"YES\n";
}
}
One issue is this in your main program:
graph->edge[i].s=v1-1;
You created a single edge. If i is greater than 0, then this is an out-of-bounds access.
Look how you created edge in the create function:
graph->edge=(struct Edge*)malloc(sizeof (struct Edge));
That allocation holds a single edge, not multiple edges. Given how you coded the rest of your program in a C-like fashion, what you probably wanted is this:
graph->edge=(struct Edge*)malloc(sizeof(Edge) * e);
Also, you should strive to not use single-letter variable names. It is hard to read code with e, v, etc. as member variable names. Name those items m_edge, m_vertex or something that is more descriptive.
Related
I am not able to figure out what is wrong with my top down knapsack dp approach, its failing testcases on below link, need help.
Question link: https://www.interviewbit.com/problems/0-1-knapsack/
Here is my code:
int fin(int i,int wt,int curprofit,vector<int>&A,vector<int>&B,int C,int n,vector<vector<int>>&dp)
{
if(i==n)
return curprofit;
if(dp[i][wt]!=-1)
return dp[i][wt];
int ret=0;
ret=max(ret,fin(i+1,wt,curprofit,A,B,C,n,dp));
if(wt+B[i]<=C)
{
ret=max(ret,fin(i+1,wt+B[i],curprofit+A[i],A,B,C,n,dp));
}
return dp[i][wt]= ret;
}
int Solution::solve(vector<int> &A, vector<int> &B, int C) {
int n=A.size();
vector<vector<int>>dp(n+1,vector<int>(C+1,-1));
return fin(0,0,0,A,B,C,n,dp);
}
Here's the fix, but I'd suggest you brush up on your recursion knowledge.
Calculate the max profit on the fly, not passing as the parameter. Otherwise, you'll need to put curprofit also in the dp state which will be costly. You may also see the output by removing the dp[][] caching. Just put up a correct recursive solution & memoize it.
int fin(int i,int wt,vector<int>&A,vector<int>&B,int C,int n,vector<vector<int>>&dp)
{
if(i==n)
return 0;
if(dp[i][wt]!=-1)
return dp[i][wt];
int ret=0;
ret=max(ret,fin(i+1,wt,A,B,C,n,dp));
if(wt+B[i]<=C)
{
ret=max(ret,fin(i+1,wt+B[i],A,B,C,n,dp) + A[i]);
}
return dp[i][wt]= ret;
}
int Solution::solve(vector<int> &A, vector<int> &B, int C) {
int n=A.size();
vector<vector<int>>dp(n+1,vector<int>(C+1,-1));
return fin(0,0,A,B,C,n,dp);
}
Original Code:
typedef struct {
int x;
int y;
} Point;
int main() {
Point point = {1, 2};
printf("%d %d\n", point.x, point.y);
return 0;
}
Use refactor to extract a method:
typedef struct {
int x;
int y;
} Point;
void PrintPoint(Point *point)
{
printf("%d %d\n", (*point).x, (*point).y);
}
int main() {
Point point = {1, 2};
PrintPoint(&point);
return 0;
}
But I want the generated PrintPoint function is like this:
void PrintPoint(Point *point)
{
printf("%d %d\n", point->x, point->y);
}
Is there a configuration in CLion to change (*pStru). to pStru-> when extracting a method?
Unfortunately there is no way to configure the behaviour. There is a bug in CLion tracker about your case. https://youtrack.jetbrains.com/issue/CPP-2193
Maybe it's time to fix it.
I'm solving one of the algorithms problem from university to implemet queue using stacks.
I've got my logic right i guess but the numbers are getting printed in the form of 12-256, 13-256, 14-256 instead of 12,13,14.
Here's my C++ Code,
#include <iostream>
using namespace std;
class Stack{
private:
int arr[200];
int tos = -1;
public:
bool empty(){
return (tos == -1)?true:false;
}
void push(int element){
arr[++tos] = element;
}
int pop(){
return arr[tos--];
}
void show(){
if(tos == -1){
cout<<"stack empty";
}else{
for(int i=tos;i>0;i--)
cout<<arr[i]<<"\t";
}
}
};
class Queue{
private:
Stack s1,s2;
public:
void enQueue(int x){
//just using s1 to add new elements
s1.push(x);
}
int deQueue(){
if(s1.empty())
throw 'e';
else{
int e;
while(!s1.empty()){
e = s1.pop();
s2.push(e);
}
cout<<"\nelement to be removed:"<<s2.pop();
if(s2.empty())
throw 'f';
else{
int e;
while(!s2.empty()){
e = s2.pop();
s1.push(e);
}
}
}
}
};
int main()
{
try{
Queue q1;
q1.enQueue(12);
q1.enQueue(13);
q1.enQueue(14);
q1.enQueue(15);
cout<<q1.deQueue();
cout<<q1.deQueue();
cout<<q1.deQueue();
cout<<q1.deQueue();
}catch(char c){
cout<<"\nstack empty!";
}
return 0;
}
I'm basically a Python Guy so i'm not able to figure out what's wrong with this code.
I'm new to C++, so please guide me through this.
Thanks in advance!
deQueue suffers from the following problems.
It doesn't return anything.
It's OK for s2 to be empty after its top has been popped.
Here's an updated version that should work.
int deQueue(){
if(s1.empty())
throw 'e';
int e;
while(!s1.empty()){
e = s1.pop();
s2.push(e);
}
int ret = s2.pop();
cout<<"\nelement dequeued:"<< ret;
// This is not correct.
// It's OK for s2 to be empty after its top has been popped.
// if(s2.empty())
// throw 'f';
while(!s2.empty()){
e = s2.pop();
s1.push(e);
}
return ret;
}
Suggestion for further improvement
Queue does not need two Stack objects as member variables. s2 can be a function local variable in deQueue.
class Queue
{
private:
Stack s;
...
};
If you decide to make that change, you'll have to update enQueue and deQueue accordingly.
#include <stdio.h>
#include <stdlib.h>
struct linked {
int data;
struct linked *next;
}
*head,*ptr,*tmp;
void display(struct linked *head)
{
tmp=malloc(sizeof(struct linked));
tmp=head;
do
{
printf("%d ",tmp->data);
tmp=tmp->next;
} while(tmp->next!=NULL);
}
struct linked *createlist(struct linked *head)
{
int i,ch;
ptr=malloc(sizeof(struct linked));
//head=(struct linked *)malloc(sizeof(struct linked));
head=ptr=tmp=NULL;
printf("Enter number of elements you want in the list!");
scanf("%d",&ch);
printf("Enter the elements!\n");
for(i=0;i<ch;i++)
{
int ele;
tmp=malloc(sizeof(struct linked));
printf("Enter the element %d= ",i+1);
scanf("%d",&ele);
tmp->data=ele;
ptr->next=tmp;
ptr=tmp;
ptr->next=NULL;
if(head==NULL)
head=ptr;
}
return head;
}
int main(void)
{
// your code goes here
head=malloc(sizeof(struct linked));
head=createlist(head);
display(head);
return 0;
}
The problem here is i don't know whether I have allocated the memory correctly or is there any problem in my insertion of node. Please help i am new to this. Please give a suggestion about how do I debug the runtime errors in code how to find them where they are actually. Thanks.
EDIT: I got the error. First I was allocating memory needlessly. To head and ptr. Also in createlist() , I was using
createlist(struct linked *head)
calling as createlist(head)
from main().
This was leading to a call by value actually. That's why even after the creation of the list, the display() was not being called just because the head in createlist() was local to the function hence global head wasn't holding the front of the list. So, no way to traverse and that was generating the error.
Thanks for the help all.
Try this code instead of your code...
#include <stdio.h>
#include <stdlib.h>
typedef struct linked {
int data;
struct linked *next;
};
struct linked *head,*ptr,*tmp;
void display()
{
tmp=head;
do
{
printf("%d ",tmp->data);
tmp=tmp->next;
} while(tmp!=NULL);
}
void createlist()
{
int i,ch;
printf("Enter number of elements you want in the list!");
scanf("%d",&ch);
printf("Enter the elements!\n");
for(i=0;i<ch;i++)
{
int ele;
tmp=(struct linked*)malloc(sizeof(struct linked));
printf("Enter the element %d= ",i+1);
scanf("%d",&ele);
tmp->data=ele;
tmp->next=NULL;
if(head==NULL){
head=tmp;
ptr=head;
}
else{
ptr->next=tmp;
ptr=ptr->next;
}
}
//return head;
}
int main(void)
{
// head=malloc(sizeof(struct linked));
createlist();
display();
return 0;
}
While creating linked list you have to remember some cases..
1 - At first time when linked list is creating head is NULL and take action according to that
i.e code given in if condition in for loop
2 - after head node is got created you have to attach all the remaining node at the end of last created linked list
i.e code given in else condition in for loop
And if your creating a global variables then no need to pass those variable as a argument to the function
Global variables are visible to each and every function.
In this particular part of code Xcode finds the following error: Reference to 'move' is ambiguous. Additionally, it says that: enumeration value 'move' not handled in switch; which is a nonsense since the class with that value is included.
while(!done){
//m=rand()%NUM;
for(m=0;m<NUM;++m){
if(piece[m].onBoard()){
sitRep=getIntel(piece,m);
r=piece[m].recommend(sitRep);
switch(r){
case nothing: break;
case lft: piece[mn].turnLeft(); break;
case rght: piece[m].turnRight(); break;
case rear: piece[m].aboutFace(); break;
case move:
piece[m].moveForward();
if(piece[m].getX()<0||piece[m].getX()>=DIM)piece[m].die();
if(piece[m].getY()<0||piece[m].getY()>=DIM)piece[m].die();
break;
case attck:
hits=piece[m].attack();
makeSuffer(piece,m,hits);
break;
}
if(line[0]=='q')done=true;
}
}
The Class is as follows:
enum provinceName {anjou, flandre, gascogne, bretagne};
enum compassPoint {U, R, D, L};
enum recommendation {move, nothing, lft, rght, rear, attck};
enum id {empty, ally, enemy, abyss};
// this struct is given to the unit when a recommendation is requested
struct intel{
id inFront;
int inFrontNum;
id inRear;
int inRearNum;
id inLeft;
int inLeftNum;
id inRight;
int inRightNum;
compassPoint nearestEnemyDir;
int nearestEnemyDist;
int nearestEnemyNum;
compassPoint weakestEnemyDir;
int weakestEnemyDist;
int weakestEnemyNum;
compassPoint strongestEnemyDir;
int strongestEnemyDist;
int strongestEnemyNum;
compassPoint nearestAllyDir;
int nearestAllyDist;
int nearestAllyNum;
compassPoint weakestAllyDir;
int weakestAllyDist;
int weakestAllyNum;
compassPoint strongestAllyDir;
int strongestAllyDist;
int strongestAllyNum;
};
class gamePiece{
public:
// return the status of the alive variable
bool onBoard();
// return the current x value
int getX();
// return the current y value
int getY();
// return the current direction
compassPoint getDir();
// return the number of soldiers in the unit
int getNumElements();
// return the province
provinceName getProvince();
// set alive to false
void die();
// change the direction for a left turn
void turnLeft();
// change the direction for right turn
void turnRight();
// change the direction for an about face
void aboutFace();
// change x and y for a forward move
void moveForward();
// roll a die for each soldier in the unit.
// each 5 or 6 counts as a 'hit'.
// return the number of hits.
int attack();
//return lft, rght, rear, move, attck, or nothing
recommendation recommend(intel sitRep);
// reduce the number of soldiers by hits
int suffer(int hits);
// construct a nonliving gamepiece
gamePiece();
// construct a living gamepeice
gamePiece(int col, int row, compassPoint direction, int num, provinceName p);
private:
int numSoldiers;
int x;
int y;
compassPoint dir;
provinceName province;
bool alive;
};
Can someone please find out what seems to be the problem?
Thank you.
might it be case lft: piece[mn].turnLeft(); break;? whats the mn? isn't it just supposed to be m? I am on the same assignment by the way.