I wrote the following C++ program to implement breadth first search to solve this problem of finding shortest path for all the nodes from the source.
#include<iostream>
#include<vector>
#include<string.h>
#include<queue>
using namespace std;
int main()
{
int test;
cin >> test;
while(test--)
{
int m,n,source;
cin >> n >> m;
bool visited[n+1];
int dist[1001];
queue<int> q;
memset(dist, -1, sizeof(dist));
vector<int> adj[1001];
for(int i = 0; i < m; i++)
{
int a, b;
cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
}
cin >> source;
dist[source] = 0;
visited[source] = true;
q.push(source);
while(q.size())
{
int v = q.front();
q.pop();
for(int i : adj[v])
{
if(!visited[i])
{
q.push(i);
dist[i] = dist[v] + 6;
visited[i] = true;
}
}
}
for(int i = 1; i <= n; i++)
{
if(i != source)
{
cout << dist[i] << " ";
}
}
cout << "\n";
}
}
It works well if the value of test is 1, but when the value is 2 or more, some values of the boolean array "visited" become 1 in the second and later iterations. I do not understand why and how it happens as I declare the boolean array in every iteration and the default value for its elements is 0. Can somebody please explain this.
I declare the boolean array in every iteration and the default value for its elements is 0.
No, it's not 0. There are no default values for C++ simple types. My bet is you propably get some random values, as your array isn't initialised automatically.
You aren't initialising the array, and local arrays are not zero initialised, so explicit initialisation is needed.
Related
This question already has answers here:
Segmentation Fault (SIGSEGV) when getting data as input in the vector of struct
(2 answers)
Closed 2 years ago.
Getting SIGESV error in following cpp code, kindly check.
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n, m;
int sa = 0, sb = 0, c = 0;
cin >> n >> m;
vector<int> a;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
vector<int> b;
for (int i = 0; i < m; i++) {
cin >> b[i];
}
int k = min(n, m);
while (k--) {
sa = accumulate(a.begin(), a.end(), 0);
sb = accumulate(b.begin(), b.end(), 0);
if (sb >= sa) {
swap(*min_element(a.begin(), a.end()),
*max_element(b.begin(), b.end()));
c++;
} else {
break;
}
}
if (sb >= sa) {
cout << "-1" << endl;
} else {
cout << c << endl;
}
}
return 0;
}
The code asks for two arrays and swaps only if array a has a summation less than array b.
Getting error as SIGESV, also can take 'b' array as an input, what to do?
When you're doing cin >> a[i], a is still empty, so attempting to access its i-th element produces a segfault. Resize it before with a.resize(n) or initialise it with the proper size: vector<int> a(n);
The size and capacity of vector a is 0 and never changes.
This code is broken:
vector<int> a;
for(int i=0;i<n;i++){
cin>>a[i];
}
operator[]() does not grow the vector. You are assigning values to memory that does not belong to a.
You want a.push_back(i) at a minimum. What you probably really want is:
vector<int> a;
a.reserve(n);
for (int i = 0; i < n; ++i) {
int tmp;
cin >> tmp;
a.push_back(tmp);
}
Reserving memory stops the vector from re-allocating. Not doing it in a constructor also stops default initialization of all elements.
The same goes for the b vector.
You also never change the values of sa or sb, but that shouldn't crash anything, it's just a logic error from what I can see.
The file as a whole is also rife with bad practices. "Competitive" coding sites actively make you a worse programmer.
When you know size you need while declaring vector you should declare vector like this
vector<int>arr(n);
vector<int>arr2(m);
this will create an vector of size n will value being zero at all indexes in vector at initialization.
Don't use <bits/stdc++.h> and trying coming up for better name for variables it will really help you as well as us. I know this is compeitive programming question but still.
I need help with this code.
What I want is to make a parametric constructor and initialise/set the value of array in it.
Question: Make a class with arrays of integers and initialise it in a constructor. Then find the smallest and largest numbers using functions.
But I am stuck at how to initialise the array in the constructor.
I want to take data input in both ways
(1) By user, using cin
(2) By giving my own values
class Numbers
{
int Arr[3];
public:
Numbers() //default constructor
{
for (int i=0 ; i<=2 ; i++)
{
Arr[i]=0;
}
}
Numbers(int arr[]) //parameteric constructor
{
for (int i=0;i<=2;i++)
{
Arr[i]=arr[i];
}
}
};
int main()
{
int aro[3] = {0,10,5};
Numbers obj (aro);
return ;
}
The solution is pretty simple. I've made a new program from start again (for sake of understanding). According to your requirement, you wants to get input of array elements from the user dynamically and assign them to a constructor and use a method to print the highest value.
Consider the following code:
#include <iostream>
using namespace std;
const int N = 100;
class Numbers
{
int largest = 0;
public:
Numbers(int, int[]);
void showHighest(void)
{
cout << largest << endl;
}
};
Numbers::Numbers(int size, int arr[])
{
for (int i = 0; i < size; i++)
{
if (arr[i] > largest)
{
largest = arr[i];
}
}
}
int main(void)
{
int arrays[N], total;
cout << "How many elements? (starts from zero) ";
cin >> total;
for (int i = 0; i < total; i++)
{
cout << "Element " << i << ": ";
cin >> arrays[i];
}
Numbers n(total, arrays);
n.showHighest();
return 0;
}
Output
How many elements? (starts from zero) 3
Element 0: 12
Element 1: 16
Element 2: 11
16
Note: I've initialized a constant number of maximum elements, you can modify it. No vectors, etc. required to achieve so. You can either use your own values by removing the total and its followed statements and use only int arrays[<num>] = {...} instead. You're done!
Enjoy coding!
I suggest to use std::vector<int> or std::array<int>.
If you want initialize with custom values you can do std::vector<int> m_vec {0, 1, 2};
Thank you so much for your help. I was basically confused about how to use arrays in a constructor and use setters/getters for arrays in a class. But you all helped a lot. Thanks again.
Numbers(int arr[])
{
for (int i=0;i<=9;i++)
{
Arr[i]=arr[i];
}
Largest=Arr[0];
Smallest=Arr[0];
}
void Largest_Number()
{
header_top("Largest Number");
Largest=Arr[0]; //Using this so we make largest value as index zero
for (int i=0 ; i<=9 ; i++)
{
if(Arr[i]>Largest)
{
setLargest( Arr[i] );
}
}
cout<<"Largest Number: "<<getLargest()<<endl;
}
So, I need to make a function that is going to return the chromatic number of a graph. The graph is given through an adjecency matrix that the function finds using a file name. I have a function that should in theory work and which the compiler is throwing no issues for, yet when I run it, it simply prints out an empty line and ends the program.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int Find_Chromatic_Number (vector <vector <int>> matg, int matc[], int n) {
if (n == 0) {
return 0;
}
int result, i, j;
result = 0;
for (i = 0; i < n; i++) {
for (j = i; j < n; j++) {
if (matg[i][j] == 1) {
if (matc[i] == matc[j]) {
matc[j]++;
}
}
}
}
for (i = 0; i < n; i++) {
if (result < matc[i]) {
result = matc[i];
}
}
return result;
}
int main() {
string file;
int n, i, j, m;
cout << "unesite ime datoteke: " << endl;
cin >> file;
ifstream reader;
reader.open(file.c_str());
reader >> n;
vector<vector<int>> matg(n, vector<int>(0));
int matc[n];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
reader >> matg[i][j];
}
matc[i] = 1;
}
int result = Find_Chromatic_Number(matg, matc, n);
cout << result << endl;
return 0;
}
The program is supposed to use an freader to convert the file into a 2D vector which represents the adjecency matrix (matg). I also made an array (matc) which represents the value of each vertice, with different numbers corresponding to different colors.
The function should go through the vector and every time there is an edge between two vertices it should check if their color value in matc is the same. If it is, it ups the second vale (j) by one. After the function has passed through the vector, the matc array should contain n different number with the highest number being the chromatic number I am looking for.
I hope I have explained enough of what I am trying to accomplish, if not just ask and I will add any further explanations.
Try to make it like that.
Don't choose a size for your vector
vector<vector<int> > matg;
And instead of using reader >> matg[i][j];
use:
int tmp;
reader >> tmp;
matg[i].push_back(tmp);
I am very very new to C++ and I am trying to call the function "jacobi" which performs a user specified number of iterations for the jacobi method (or at least I hope so). On the line where I call 'jacobi' I get the error "No matching function to call to "jacobi". I have read other posts similar to this one and have tried to apply it to my own code but I have been unsuccessful. Maybe there are other issues in my code causing this problem. As mentioned I am very new C++ so any help would be appreciated and please break it down for me.
#include <iostream>
using namespace std;
void jacobi (int size, int max, int B[size], int A[size][size], int init[size], int x[size]){
////
//// JACOBI
////
int i,j,k,sum[size];
k = 1;
while (k <= max) // Only continue to max number of iterations
{
for (i = 0; i < size; i++)
{
sum[i] = B[i];
for (j = 0; j < size; j++)
{
if (i != j)
{
sum[i] = sum[i] - A[i][j] * init[j]; // summation
}
}
}
for (i = 0; i < size; i++) ////HERE LIES THE DIFFERENCE BETWEEN Guass-Seidel and Jacobi
{
x[i] = sum[i]/A[i][i]; // divide summation by a[i][i]
init[i] = x[i]; //use new_x(k+1) as init_x(k) for next iteration
}
k++;
}
cout << "Jacobi Approximation to "<<k-1<<" iterations is: \n";
for(i=0;i<size;i++)
{
cout <<x[i]<< "\n"; // print found approximation.
}
cout << "\n";
return;
}
int main (){
// User INPUT
// n: number of equations and unknowns
int n;
cout << "Enter the number of equations: \n";
cin >> n;
// Nmax: max number of iterations
int Nmax;
cout << "Enter max number of interations: \n";
cin >> Nmax;
// int tol;
// cout << "Enter the tolerance level: " ;
// cin >> tol;
// b[n] and a[n][n]: array of coefficients of 'A' and array of int 'b'
int b[n];
int i,j;
cout << "Enter 'b' of Ax = b, separated by a space: \n";
for (i = 0; i < n; i++)
{
cin >> b[i];
}
// user enters coefficients and builds matrix
int a[n][n];
int init_x[n],new_x[n];
cout << "Enter matrix coefficients or 'A' of Ax = b, by row and separate by a space: \n";
for (i = 0; i < n; i++)
{
init_x[i] = 0;
new_x[i] = 0;
for (j = 0; j < n; j++)
{
cin >> a[i][j];
}
}
jacobi (n, Nmax, b, a, init_x, new_x);
}
The problem:
There are several problems, related to the use of arrays:
You can't pass arrays as parameter by value.
You can't pass multidimensional arrays as parameter if the dimensions are variable
You can't define arrays of variable length in C++
Of course there are ways to do all these kind of things, but it uses different principles (dynamic allocation, use of pointers) and requires additional work (especially for the access of multidimensional array elements).
Fortunately, there is a much easier solution also !
The solution:
For this kind of code you should go for vector : these manage variable length and can be passed by value.
For the jacobi() function, all you have to do is to change its definition:
void jacobi(int size, int max, vector<int> B, vector<vector<int>> A, vector<int> init, vector<int> x) {
int i, j, k;
vector<int> sum(size); // vector of 'size' empty elements
// The rest of the function will work unchanged
...
}
Attention however: the vectors can be of variable size and this jacobio implementation assumes that all the vectors are of the expected size. In professional level code you should check that it's the case.
For the implementation of main(), the code is almost unchanged. All you have to do is to replace array definitions by vector definitions:
...
vector<int> b(n); // creates a vector that is initialized with n elements.
...
vector<vector<int>> a(n,vector<int>(n)); // same idea for 2 dimensional vector (i.e. a vector of vectors)
vector<int> init_x(n), new_x(n); // same principle as for b
...
I've read about 2d dynamic arrays but I obviously haven't quite got my head around it as this program doesn't work. The program seems to lie in displaying the array.
The input file is a text file with V and E on the first line with a 'tab indent' between them. The input vertices are on the next lines again tab indented with a new set on each line. On DevCpp it says there is a segmentation fault. Any help would be very much appreciated. thanks.
#include <iostream>
#include <fstream>
using namespace std;
#define maxV 100
#define unseen 0
typedef int Vertex;
class Graph {
private:
int V, E;
int**adj;
public:
Graph(char filename[]);
void display();
};
// constructor ask you for file name
Graph::Graph(char fname[]) {
Vertex u,v;
int j;
ifstream f;
f.open(fname, ios::in);
if(!f) {
cout << "\nError: Cannot open file\n";
return;
}
//Input number of vertices and edges
f >> V >> E;
int** adj = new int*[V];
for (int i=0;i<=V;i++)
{
adj[i]= new int[V];
}
for(int x=0;x<=V; ++x) // initially 0 array
{
for (int y=0;y<=V;++y)
adj[x][y] = 0;
}
// Set diagonal to 1
for(int z=0; z<=V; ++z)
adj[z][z]=1;
for (j =0;j<=E;++j)
{
f>>u>>v;
adj[u][v] = 1;
adj[v][u] = 1;
}
}
// This method displays the adjacency lists representation.
void Graph::display(){
int a,b,c;
for (a=0;a<=V;++a)
{
cout << a << " ";
}
cout << endl;
for (b=0;b<=V;++b)
{
cout << b << "| ";
for (c=0;c<=V;++c)
{
cout<<adj[b][c]<<"| ";
}
cout<<endl;
}
}
int main()
{
char fname[20];
cout << "\nInput name of file with graph definition: ";
cin >> fname;
Graph g(fname);
g.display();
}
//Input number of vertices and edges
f >> V >> E;
// You're hiding your member variable in the following line, leading to an incorrect initialization
// int** adj = new int*[V];
adj = new int*[V];
for (int i=0;i<=V;i++)
{
adj[i]= new int[V];
}
I see two significant problems just in the code that initializes the data array. First, a loop like this
for (int i=0;i<=V;i++)
loops over one more element than actually exists in the array. The correct form of a loop if the array is V elements long is
for (int i=0;i<V;i++)
That's "less than" rather than "less than or equal".
Secondly, you allocate both the array of pointers to be V pointers long, and than the individual columns to be V elements long as well; but later you use the same array and expect it to be V x E in size. Altogether, then, I think the allocation code ought to be
int** adj = new int*[V];
for (int i=0;i<V;i++)
{
adj[i]= new int[E];
}
There are likely to be other errors elsewhere, but at least I've got you started.
I don't know which line is causing the segmentation fault but here are some things to look at:
for (j =0;j<=E;++j)
{
f>>u>>v;
adj[u][v] = 1;
adj[v][u] = 1;
}
Are u and v guaranteed to be less than V? If not you could be writing outside the bounds of the matrix.
What happens when j == E? You are trying to read a line past the last line in the file. You should be checking instead for j < E. A better way still would be to ignore E all together and just do this:
while(f >> u >> v)
{
adj[u][v] = 1;
adj[v][u] = 1;
}
More likely though the segmentation fault is here:
for (b=0;b<=V;++b)
{
cout<<(b+1)<<"| ";
for (c=0;c<=V;++c)
{
cout<<adj[b][c]<<"| ";
}
cout<<endl;
}
the for loop conditionals should be checking b < V and c < V not <=. when either b or c == V you are definitely reading outside the matrix.