Implementing a Graph DFS in C++, pointers issue - c++

Sorry in advance, but some variable names and such have strange names, as I am not a native English speaker, I am also pretty new to programming.
So, I was doing a project with graphs topology sorting and similar, but I can't get DFS to work, I know that I am probably losing data because of usage of pointers in there(?), but I won't be using this adjacency list in my program any further anyway. The problem is just to get right result which in this case is when the vertex was entered (d[]) and left (f[]) but while in recursion my pointers go crazy, sometimes when I go back in recurrence (and apparently nothing else happens), I think at least because it's the first time I am using debugging function. I am sitting at this for like 8 hours already (not my first problem, but I managed to solve some, that's why code looks so ugly), and I was sitting with this debugger and didn't make any progress in over an hour, so I decided to ask, my first time using this website, I hope you can help me, and when I am a bit better I will definitely return the favor, here's the code:
#include <iostream>
#include <cstdlib>
#include <time.h>
struct m_sasiedztwa
{
int s;
int** m;
m_sasiedztwa(int a,float b) : s(a)
{
m = new int*[s];
for(int i = 0; i < s; ++i) m[i] = new int[s];
for(int j=0; j<s; ++j)
for(int k=0; k<s; ++k) if(j!=k) m[j][k]=((rand()%100)>(100*b))? 0 : 1; else m[j][k]=0;
}
~m_sasiedztwa()
{
delete[] m;
}
};
struct lista
{
int key;
lista *next;
};
struct l_nast
{
int s;
lista** arr;
l_nast(int** m, int a) : s(a)
{
lista *curr,*prev;
arr = new lista*[s];
for(int i=0;i<s;++i)
{
arr[i] = new lista;
curr = arr[i];
prev=curr;
prev->key=-1;
for(int j=0;j<s;++j)
{
if(m[i][j]==1) {curr->next= new lista;curr->key=j;prev=curr;curr=curr->next;}
}
prev->next=nullptr;
}
}
~l_nast() {delete[] arr;}
};
//Here is the issue
bool *Nowy;
int c;
int* d,*f;
void DFS(int j,l_nast l_a)
{
Nowy[j]=false;
d[j]=c++;
std::cout<<"Am I here yet..."<<j<<" "<<c<<std::endl;
while((l_a.arr[j]!=nullptr)&&(l_a.arr[j]->key!=-1))
{
std::cout<<"checking "<<(l_a.arr[j]->key)<<"...\n";
if(Nowy[l_a.arr[j]->key])
{
DFS(l_a.arr[j]->key,l_a);
}
if(l_a.arr[j]->next!=nullptr) //And I think this may be the problem, but I honestly don't know
l_a.arr[j]=l_a.arr[j]->next;
else break;
}
f[j]=c++;std::cout<<"Yohoo!"<<j<<" "<<c<<std::endl;
}
//Untill there
using namespace std;
int main()
{
srand (time(NULL));
for(int q=5; q<6; q+=5)
{
m_sasiedztwa a = m_sasiedztwa(q, 0.2);
m_sasiedztwa b = m_sasiedztwa(q, 0.4);
l_nast l_a = l_nast(a.m,q);
l_nast l_b = l_nast(b.m,q);
/*
for(int i=0; i<q; ++i)
{
for(int j=0; j<q; ++j)
{
cout << a.m[i][j] << " ";
}
cout<<endl;
}
cout<<endl;
*/
Nowy = new bool [q];
d = new int [q];
f = new int [q];
c=0;
for (int i = 0; i < q; i++)
Nowy[i] = true;
/*for(int qq=0;qq<q;qq++)
while((l_a.arr[qq]!=nullptr))
{
cout<<l_a.arr[qq]->key<<endl;
l_a.arr[qq]=l_a.arr[qq]->next;
}
*/
for(int j=0;j<q;j++)
{
if(Nowy[j]) DFS(j,l_a);
}
a.~m_sasiedztwa();
b.~m_sasiedztwa();
l_a.~l_nast();
l_b.~l_nast();
}
return 0;
}
As I said it's not pretty, sorry for troubling you, again what I need help with is to get function DFS to properly result with d[] which is a table if integers which indicate when the vertex was visited, and f[] - table when the vertex was taken from the stack, just ordering 1,2,3..., the problem is - it breaks in the middle, sometimes it does like 7/10 sometimes just 2/10 and it breaks, of course, it will have to work for bigger graphs as well. The pointers are lost and it tries to check Nowy[some big number there] and program crashes.

So, I used struct badly and made many mistakes, thanks to some comments I decided to use vector of vectors for adj matrix and vector of forward_list for adj list Here is what changed m_sasiedztwa struct
struct m_sasiedztwa
{
int s;
std::vector<std::vector<int>> m;
m_sasiedztwa(int a,float b) : s(a), m(s, std::vector<int>(s,0))
{
for(int j=0; j<s; ++j)
for(int k=0; k<s; ++k)
if(j!=k)
m[j][k]=((rand()%100)>(100*b))? 0 : 1;
}
};
l_nast struct:
struct l_nast
{
int s;
std::vector<std::forward_list<int>> arr;
l_nast(std::vector<std::vector<int>> m, int a) : s(a), arr(s)
{
for(int i=0;i<s;++i)
{
auto it = arr[i].before_begin();
for(int j=0;j<s;++j)
{
if(m[i][j]==1) {it = arr[i].emplace_after(it,j);}
}
}
}
};
and the DFS:
void DFS(int j,l_nast l_a)
{
Nowy[j]=false;
d[j]=c++;
std::cout<<"Visiting "<<j<<"as "<<c<<std::endl;
auto x=l_a.arr[j].begin();
for(auto& x: l_a.arr[j])
{
if(Nowy[x])
{
DFS(x,l_a);
}
}
f[j]=c++;std::cout<<"Leaving "<<j<<"as "<<c<<std::endl;
}

Related

BFS using deque

Really having trouble figuring out how to fix my code. I know there are obviously errors since it isn't running, but I'm unsure of what exactly they are, or how to go about fixing them. Any help/insight would be extremely appreciated. Thank you!!
struct vertices
{
int value;
int parent;
int visited;
int distance;
};
int BFS(vertices *v, int **adj_matrix, int num_nodes)
{
int target;
int cur_v = 0;
bool found = false;
int steps = 0;
cin >> target >> num_nodes;
adj_matrix [num_nodes][num_nodes];
deque<int> q;
for(int i = 0; i < num_nodes; i++)
{
v[i].visited = 0;
v[i].distance = INFINITY;
v[i].parent = 0;
v[1].visited = 1;
v[i].distance = 0;
q.push_front(v[1].value);
while(!q.empty())
{
cur_v = q.front();
q.pop_back();
v[cur_v].visited = 1;
for(int n=0; n< num_nodes; n++)
{
if(adj_matrix[cur_v][i] == n)
{
if(v[n].visited == 0)
{
v[n].visited = 1;
v[n].distance = ((v[cur_v].distance)+1);
v[n].parent = cur_v;
q.push_front(v[n].value);
steps ++;
}
}
}
}
}
return steps;
}
int main()
{
int target;
int num_nodes;
cin >> target;
cin >> num_nodes;
vertices *v = new vertices[num_nodes];
int **adj_matrix [num_nodes][num_nodes];
for(int i=0; i < num_nodes; ++i)
{
int node;
int value;
cin >> node >> value;
int num_edges;
cin >> num_edges;
for(int j=0; j<num_edges;++j)
{
int other_node;
cin >> other_node;
**adj_matrix[node][other_node] = 1;
**adj_matrix[other_node][node] = 1;
}
}
}
The first obvious error is that you are using the wrong data
structure. When you are implementing known concepts like matrix,
BFS, you need to spend a good amount of time to think about how to
implement inputs , outputs, data structures from the algorithm.
Some people like to use std::vector<std::vector<int>> for matrices. I almost always uses std::vector<int> for matrix data.
Second error is that you are mutating the algorithm. That thing is not BFS. It is not obvious at first.
You call multiple instance of BFS inside you BFS implementation. Using the same input vertices, whose elements are being modified. At the next loop, you dont start with a clean state.
You are flattening the algorithm, removing abstractions. What if you now have to use a adjency list? You have to modify the whole thing.
Third obvious error is coding style. You didnt do such a bad job because the vertices structure is self explanatory
I had to highlight all instances of cur_vto realizes that it stands for current vertex.
Using n for a counter is not a great idea.
Taking input inside the algorithm implementation is a big nono.

Polynomial Class runs fine in debugger but not when trying to build&run

So I've been trying to solve this problem for some hours but without any succes. I've got a class for Polynomial methods(set/get grade, set/get polynom's coefficients, print polynom, find every y = f(x) for a given set of numbers etc.)
However, the problem is that whenever the grade of the polynom is even, the build&run returns strange values. The debug of it runs prefectly fine. On the other side, whenever the grade is uneven, works perfectly fine for both debug and build&run. I'm thinking the problem is somewhere at dinamically allocated memory. Here's the code. Thanks
main.cpp
#include "poly_header.h"
int main()
{
Poly p;
p.AfisareValori();
return 0;
}
poly_header.h
#include <iostream>
#include <math.h>
using namespace std;
class Poly
{
private:
int grad;
int* coeficienti;
int a;
int b;
int dx;
public:
Poly();
void SetGrad();
int GetGrad();
void SetCoef();
void GetCoef();
void SetPolyn();
void PrintPoly();
void SetInterval();
void SetDistanta();
void AfisareValori();
~Poly();
};
poly_functions.cpp
#include "poly_header.h"
Poly::Poly()
{
this->grad = 0;
this->coeficienti = new int[0];
}
Poly::~Poly()
{
delete coeficienti;
}
void Poly::SetGrad()
{
int n;
cout<<"Introduceti gradul dorit al polinomului: ";
cin>>n;
this->grad = n;
}
int Poly::GetGrad()
{
cout<<"\n";
return this->grad;
}
void Poly::SetCoef()
{
int n;
this->coeficienti = new int[this->grad];
for(int i = 0; i <= this->grad; i++){
cout<<"Introduceti coeficientul "<<i<<" :";
cin>>this->coeficienti[i];
cout<<"\n";
}
}
void Poly::GetCoef()
{
cout<<"\n";
for(int i = 0; i <= this->grad; i++)
cout<<"Coeficientul asociat termenului x^"<<i<<" este:"<<this->coeficienti[i]<<"\n";
}
void Poly::SetPolyn()
{
SetGrad();
SetCoef();
}
void Poly::PrintPoly()
{
SetPolyn();
for(int i = grad; i >= 0; i--){
if(i == 0){
cout<<coeficienti[i];
break;
}
cout<<coeficienti[i]<<"*X^"<<i<<" + ";
}
}
void Poly::SetInterval()
{
int a,b;
cout<<"Introduceti capatul din stanga al intervalului: ";
cin>>a;
this->a = a;
cout<<"\n";
cout<<"Introduceti capatul din dreapta al intervalului: ";
cin>>b;
this->b = b;
cout<<"\n";
}
void Poly::SetDistanta()
{
int dx;
cout<<"Introduceti distanta dintre puncte: ";
cin>>dx;
this->dx = dx;
cout<<"\n";
}
void Poly::AfisareValori()
{
SetPolyn();
SetInterval();
SetDistanta();
int suma;
for(int i = a; i <= b; i+=dx){
suma = 0;
for(int j = 0; j <= grad; j++){
suma += coeficienti[j] * (pow (i,j));
}
cout<<"Valorea polinomului in punctul "<<i<<" este "<<suma<<"\n";
}
}
A polynomial P of degree ('grad' by your wording) N has N+1 coefficients;
In pseudo code:
length((N, N-1, ... 1, 0)) = N + 1.
thus this
void Poly::SetCoef()
{
/*...*/
this->coeficienti = new int[this->grad];
/*...*/
)
allocates one int too less.
Polynomials of even degree have an odd number N of coefficients, Polynomials of odd degree have an even number of coefficients.
I you allocate an int too less, the bucket too less for the polynomials of odd degree is at an boundary of a 2*sizeof(int) memory alignment; thus, it is likely that that bucket is not used otherwise.
This doesn't hold for even degrees, their missing bucket is within a new alignment block.
That's also the explanation for the discrepancy between debug and release mimics; the debug compiler run simply packs the memory less dense than the release compiler.
Besides that, you don't have to deal with manual field allocation at all for your purpose; e.g. std::vector and std::valarray automate that task in safe manner.

selection sort array run time error

This is my first time here. I really hope anyone can help me out there. So this is my problem. I keep getting run time error #2 something about a corrupt "arr". But the program runs fine until the end. I can't figure it out.
This is my code:
#include <iostream>
using namespace std;
void main(){
int arr1[3];
int temp;
//INPUT NUMBERS
for (int i=0; i<5;i++)
{
cin>>arr1[i];
}
cout<<endl;
//SORT
for(int c=0;c<5;c++)
{
for (int k=0;k<5;k++)
{
if(arr1[c]<arr1[k])
{
temp=arr1[k];
arr1[k]=arr1[c];
arr1[c]=temp;
}
}
}
for (int m=0; m<5; m++)
{
cout<<arr1[m]<<endl;
}
}
Try this out:
#include <iostream>
using namespace std;
int main()
{
int arr1[5];
int temp;
//INPUT NUMBERS
for (int i = 0; i < 5; i++) {
cin >> arr1[i];
}
cout << endl;
//SORT
for (int c = 0; c < 5; c++) {
for (int k = 0; k < 5; k++) {
if (arr1[c] < arr1[k]) {
temp = arr1[k];
arr1[k] = arr1[c];
arr1[c] = temp;
}
}
}
for (int m = 0; m < 5; m++) {
cout << arr1[m] << endl;
}
}
It compiles properly without any errors. The mistake you had made is in declaring the size of the array. If you want to store 5 in puts, you need to declare an array of size 5. Your code might work, but a good compiler will always give out an error.
The reason being that when you declare an array, you actually create a pointer to the first element of the array. And then, some memory regions are kept for this array, depending on the size. If you try to access an element that is outside these memory regions, you may encounter a garbage value.
Here's your code in ideone.

Having a Runtime error in this code

I am having a run-time error in this program, it has no syntax error but crashes when it is run. i am using dev-c++ 4.9.9.2. I tried to find the error but i couldn't find it. If anyone can help then please find the errors and correct me.
#include<iostream.h>
void DisplayVUID();
void DisplayReverse(char[], int);
void StoreDiagonal();
main()
{
DisplayVUID();
char a[20] = "mc123456789";
DisplayReverse(a, 20 );
StoreDiagonal();
system("pause");
}
void DisplayVUID()
{
int i;
char name[20] = "mc123456789";
cout<<"My VU id is ";
for(i=0;i<20;i++)
{
cout<<name[i];
}
cout<<endl;
}
void DisplayReverse(char a[], int arraysize)
{
int i;
cout<<"MY VU id in Reverse is ";
for(i=arraysize-1;i>=0;i--)
{
cout<<a[i];
}
cout<<endl;
}
void StoreDiagonal()
{
int a[9][9] ;
int i;
int row, col;
for (i = 0; i<9;i++)
{
for(i=0;i<9;i++)
{
a[row][col] = 0;
}
}
a[1][1] = 1;
a[2][2] = 3;
a[3][3] = 0;
a[4][4] = 2;
a[5][5] = 0;
a[6][6] = 2;
a[7][7] = 3;
a[8][8] = 9;
a[9][9] = 8;
for(i = 0 ; i < 9 ; i ++)
{
for( i = 0 ; i < 9 ; i ++)
{
cout<<a[row][col];
}
}
}
Things don't work this way on Stackoverflow, from next time onward try hard to do things on your own, do your research and then come here.There seemed to be many errors in your program but I tried to remove some bugs and finally, It works on my system. I have also recommended some nice things via comments that you can look in the program:
EDIT: I noticed that some undefined string because of unassigned spaces in the array was printed out in the reverse function but i have corrected it now.
#include<iostream>
#include<stdlib.h>
using namespace std;// use namespace otherwise cout won't work
void DisplayVUID();
void DisplayReverse(char[], int);
void StoreDiagonal();
int main()// In C++ always declare a main function like this,its good habit
{
int i=0;
DisplayVUID();
char a[20] = "mc123456789";
while(a[i]!='\0')
i++;// Did this to ensure that cout will print only up to the null character,earlier it was printing some undefined characters along with the data in the array.
DisplayReverse(a, i );
StoreDiagonal();
system("pause");
return 0;//return 0
}
void DisplayVUID()
{
//int i;
char name[20] = "mc123456789";
cout<<"My VU id is ";
//for(i=0;i<20;i++)// no need for this loop at least here
//{
cout<<name;
//}
cout<<endl;
}
void DisplayReverse(char a[], int i)
{
cout<<"MY VU id in Reverse is ";
// for(i=arraysize-1;i>=0;i--)
//{
while(i--)
cout<<a[i];//instead of the for loop traversing for the whole arraysize i have made it go up to only the null terminator this way it doesn't print undefined characters.
//}
cout<<endl;
}
void StoreDiagonal()// i don't understand by the way what this function is here for , its not an error though.
{
int a[9][9] ;
int i,j,c=1;
//int row, col;// you didn't initialize row and column and placed it inside the loop
for (i = 0; i<9;i++)
{
for(j=0;j<9;j++)
{
a[i][j] = 0;
if(i==j)
{
a[i][j]=c;//instead of manually assigning do it like this.
c++;
}
}
}
for(i = 0 ; i < 9 ; i ++)
{
for( j = 0 ; j < 9 ; j ++)
{
cout<<a[i][j];// the elements of the array don't display like a table , this is not an error but to make your output readable do it by your self
}
}
}
a[9][9]=8;
remove this line, you will be fine. Array indexing starts from 0 not 1.
Also I would like to point that in your function DisplayVUID() change i<20 to a[i]!='\0' because the values after '\0' will be garbage values.

dynamic allocation of int array in c++ and assigning value

I am new to c++ and i was trying to do folloing two things without help of std::vector( This was done earlier)
Define an array of integer and the size of array is not known to me.
Pass this array into another function and output all the values stored in array.
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = 0;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++n)
{
std::cout<<x[i];
}
}
But i can see that its not allocating memory of 10 bytes and all the time a single memory is filled up with 0.
Can anyone please help me if i am lacking something ? Or is there any alternative way for this apart from vector.
Thanks in Advance
I modified with one thing as i realized that i put ++n instead of i
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = i;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++i)
{
std::cout<<x[i];
}
}
I’m not sure I understand all yours problems but the typo
for(int i =0;i<n;++n) in testFunction led to a very long loop.
Write:
for(int i =0;i<n;++i)
this print yours n "0"