C++ Recursion Graph Coloring Segmentation Fault - c++

I am in an intro C++ class at uni, and we have a problem that I have been working on for a day or two, but I have been stuck and can't figure out why. The lab is to solve the graph-coloring problem with recursion. We input a file that has a matrix of vertices and their edges. Example-
8
0 1 0 0 0 1 1 0
1 0 1 1 1 0 0 0
0 1 0 0 0 0 1 0
0 1 0 0 1 0 0 1
0 1 0 1 0 0 1 1
1 0 0 0 0 0 1 0
1 0 1 0 1 1 0 1
0 0 0 1 1 0 1 0
With 8 being the number of vertices, and going in row-major order, 0 represents no edge an 1 represents an edge between the respective vertices. Here is the rest of my code, without comments at the moment, sorry. The code reads in a file, sets up a matrix, then uses a recursive algorithm to guess and check to see if the available colors(k) is enough to complete the graph coloring problem.
// Alex Cherecwich
// Lab7
#include <iostream>
#include <cstdlib>
#include <iomanip>
#include <fstream>
using namespace std ;
// -----------------------------------------------------------------
class graph
{
private:
int n;
int k;
int ** G;
int the_colors[];
bool adj_vertex(int m, int c);
public:
graph(int x){k = x;}
void read_graph(char * fname);
void set_color();
bool graph_color(int m);
} ;
// -----------------------------------------------------------------
void graph::read_graph(char *fname)
{
ifstream ifs;
ifs.open(fname);
if(!ifs.is_open())
{
cerr << "Can not open (read) file '" << fname <<"'"<< endl;
exit(1);
}
ifs >> n;
G = new(nothrow) int *[n];
for(int b = 0; b < n; b++)
{
G[b]= new(nothrow) int [n];
for(int j=0; j< n; j++)
{
ifs >> G[b][j];
}
}
ifs.close();
}
// -----------------------------------------------------------------
void graph::set_color()
{
the_colors[n];
for(int i = 0; i < n; i++)
{
the_colors[i] = -1;
}
}
// -----------------------------------------------------------------
bool graph::adj_vertex(int m, int c)
{
for(int i = 0; i < n; i++)
{
if(G[m][i] == 1 && the_colors[i] == c)
{
return false;
}
}
return true;
}
// -----------------------------------------------------------------
bool graph::graph_color(int m)
{
if(m == n)
{
cout << "Solution Found" << endl;
cout << "Vertex" << " " << "Color" << endl;
for(int i = 0; i < n; i++)
{
cout << i << " " << the_colors[i] << endl;
}
return true;
}
else
{
for(int c = 0; c < k; c++)
{
if(adj_vertex(m, c))
{
the_colors[m] = c;
bool r = graph_color(m + 1);
if(r) return true;
the_colors[m] = -1;
//return false;
}
}
return false;
}
}
// -----------------------------------------------------------------
int main(int argc, char **argv)
{
int k = atoi(argv[1]);
graph B(k);
B.read_graph(argv[2]);
B.set_color();
if(B.graph_color(0) == false)
{
cout << "No Solution Found" << endl;
}
return 0;
}
The input should be a.out k(number of colors) and the name of the file to be read. Everything works, and I get the right outputs I believe from what I have tested on paper, but I always get a Segmentation fault(core dumped) error message. I am not sure why this is, perhaps I am trying to access some index that doesn't exist, I am not sure. Also, whenever I use 3 as the number of colors(k) on the matrix above, I get this output, which is correct.
Solution Found
Vertex Color
0 0
1 1
2 0
3 2
4 0
5 1
6 2
7 1
Segmentation fault (core dumped)
However, whenever I have k>=4 on the same matrix above, I get this output, which still works but isn't the most efficient solution, which I we are supposed to output every time if a solution is possible.
Solution Found
Vertex Color
0 0
1 1
2 0
3 0
4 2
5 1
6 3
7 1
Segmentation fault (core dumped)
Also, the code works when there are not enough colors, but it still gives a Segmentation fault(core dumped) message. Either way, any and all help would be appreciated!

You never allocate memory for the_colors. It's pointing wherever, and you're lucky your program gets as far as it does.

int the_colors[];
This is not legal C++. It is an extension provided by your compiler, and it doesn't provide arrays that magically adjust their size as needed. Don't use it.
C++ has std::vector, use it for all your array-related needs.

Related

i want to print no in 2d array by taking inputs but it will give wrong output

i am using vectors and i want to print same output as per the input by using the exact method in the code
trying to using 2 d vectors
//the cause of the error is the while j loop part
i mark it in the code
#include <bits/stdc++.h>
using namespace std;
// vector<int> dynamicArray(int *n,int *q)
// {
// }
int main()
{
int n, size, a;
cin >> n >> size;
vector<vector<int> > q;
// vector<int>q;
vector<int> q1;
for (int i = 0; i < size; i++) {
int j = 3;
// here error occurs
while (j > 1) {
cin >> a;
q1.push_back(a);
j--;
}
q.push_back(q1);
}
for (int i = 0; i < q.size(); i++) {
for (int j = 0; j < 3; j++) {
cout << q[i][j];
}
cout << endl;
}
return 0;
}
// here are the inputs
2 5
1 0 5
1 1 7
1 0 3
2 1 0
2 1 1
expected output
1 0 5
1 1 7
1 0 3
2 1 0
2 1 1
//here are the output
resulting output
100
105
105
105
105
I think that your code has 2 bugs in it. Firstly, you are not clearing vector q1 after every processed line, thus your code is pushing to q vector with the same prefix of values every time and that's why the output is the same line repeated multiple times.
Secondly, i think that you are trying to read 3 elements in every line but currently because of condition while(j > 1) you are reading only 2 elements. Try to change it to while(j > 0).

Why is the code after my for loop being ignored?

I don't think you'll need to know the context of the problem to answer this question, but I'll give it just in case.
-In the past N weeks, we've measured the amount of rainfall every day, and noted it down for each day of the week. Return the number of the first week of the two week period where there were the most days without rain.
The code gives no warnings or errors, and if I try to print dryestweeks inside the second for loop, then it returns the correct answer. However, all of the code after the second for loop seems to be getting ignored, and I'm getting Process returned -1073741819 (0xC0000005). The issue has to lie in the 2nd for loop, because if I comment it out then both "test2" and dryestweeks get printed, and the program returns 0.
#include <iostream>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
int main() {
int weeks;
cin >> weeks;
vector<int> v[weeks];
for (int i = 0;i < weeks; i++) {
int a, b, c, d, e, f, g;
cin >> a >> b >> c >> d >> e >> f >> g;
v[i].push_back(a);
v[i].push_back(b);
v[i].push_back(c);
v[i].push_back(d);
v[i].push_back(e);
v[i].push_back(f);
v[i].push_back(g);
}
int mostdrydays = 0;
int dryestweeks = 0;
for (int i = 0; i < weeks; i++) {
int weeklydrydays = count(v[i].begin(), v[i].end(), 0);
int nextweekdrydays = count(v[i+1].begin(), v[i+1].end(), 0);
int biweeklydrydays=weeklydrydays+nextweekdrydays;
if (biweeklydrydays > mostdrydays) {
mostdrydays = biweeklydrydays;
dryestweeks = i + 1;
}
}
cout << "test2" << endl;
cout << dryestweeks << endl;
return 0;
}
An example of an input would be:
6
5 10 15 20 25 30 35
0 2 0 0 0 0 0
0 0 0 1 0 3 0
0 1 2 3 4 5 6
5 1 0 0 2 1 0
0 0 0 0 0 0 0
The program should print "2" with the above input.
The second loop has an overflow.
You first defined v[weeks] and then the second loop goes from [0, weeks[ but you are retrieving the next week with v[i + 1]. I don't know exactly what are you are trying to achieve, but if you do
for(int i = 0; i < weeks - 1; i++)
{
...
}
it executes properly.
For the given example of input, in the last iteration (i = 5) of the second loop, index i + 1(=6) will be out of the bound for v[i + 1] (legal indices for v will be from 0 to 5).
The second loop is iterating one more time than required.

Getting unknown values along with answer

Smaller Greater Equal Numbers
PrepBuddy has N baskets containing one fruit each with some quality factor(ith basket have Ai quality factor) and Tina has one single basket with one fruit having quality factor K. She wants to know how many PrepBuddy's baskets have quality factor less(L) than K, how many baskets have quality factor more(M) than K and how many baskets have quality factor equal(E) to K.
Input format
The first line contains an integer T, representing the number of test cases.T test cases follow,First linecontains two space-separated integers N and K.The second line contains N space-separated integers representing the quality factor of the basket.
Output format
For each test case on a new line, print three space-separated integers representing the values of L, M,and E.
Constraints
1<=T<=100
1<=N,K<=10^5
−10^6<=A[i]<=10^6
Sum of all N over any test case file doesn't exceed 5∗10^6
Time Limit
1 second
Example
Input
2
5 2
-1 0 -3 1 2
5 3
1 -1 -5 2 4
Output
4 0 1
4 1 0
Sample test case explanation
In the first test case,
K=2, the baskets with quality factor smaller than K are [1,2,3,4], there is no basket which has quality factor more than K and there is one basket [5] which have quality factor equal to K.
My solution
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
ll arr[n];
for (ll i = 0; i < n; i++) {
cin >> arr[i];
}
int less = 0, more = 0, equal = 0;
for (ll i = 0; i < n; i++) {
if (arr[i] < k) {
less++;
} else if (arr[i] > k) {
more++;
} else {
equal++;
}
cout << less << " " << more << " " << equal << " ";
}
cout << endl;
}
return 0;
}
Input
2
5 2
-1 0 -3 1 2
5 3
1 -1 -5 2 4
Output
1 0 0 2 0 0 3 0 0 4 0 0 4 0 1
1 0 0 2 0 0 3 0 0 4 0 0 4 1 0
Why am I getting additional numbers like 1 0 0 2 0 0 3 0 0 4 0 0 along with my answer.How to correct this?? Please help
The error in your code was quiet simple, and easy to debug. You were printing the output every run through the array, thus, getting all these extra prints.
How does it become easy to debug? Reorganizing the code so it will be more readable, made it quiet possible. Actually, the fix was moving the line:
cout<<less<<" "<<more<<" "<<equal<<" ";
Two line lower than it was.
In order to demonstrate it, here is the code fixed and organized:
#include <iostream>
#include <vector>
#include <cstdint>
int main()
{
int t;
std::cin >> t;
while(t--)
{
std::int64_t n,k;
std::cin >> n >> k;
std::vector<int> vec{n};
for(std::size_t i = 0; i < n; ++i)
{
std::cin >> vec[i];
}
int less=0, more=0, equal=0;
for (std::size_t i = 0; i < n; i++)
{
if (vec[i] < k)
{
less++;
}
else if (vec[i] > k)
{
more++;
}
else
{
equal++;
}
// The next output line was here, under the for loop!!!
}
std::cout << less << " " << more<< " " << equal << " "; // this is its place!
std::cout << std::endl;
}
return 0;
}
I have made only 3 changes:
Removed the using namespace std; and #include <bit/stdc++.h>.
Realigned the code according to its logical order - each new scope has its own indentation level, showing which command runs in which scope, revealing the mistake.
Used proper types to each thing: In C++ there are no dynamic arrays in the format arr[n], thus, you need to use std::vector. Also, there are fixed size lengths in cstdint, and you should use those to ensure you are using the right type. Also, prefer using unsigned values when possible, for example, when indexing, use either std::size_t, std::uint32_t or std::uint64_t.
This code worked fine for me
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T,N,K,arr[N];
cin>>T;
while(T--)
{
cin>>N;
cin>>K;
for(int i=0;i<N;i++)
{
cin>>arr[i];
}
int L=0,M=0,E=0;
for(int i=0;i<N;i++)
{
if(arr[i]<K){
L++;
}
else if(arr[i]>K)
{
M++;
}
else{
E++;
}
}
cout<<L<<" "<<M<<" "<<E<<endl;
}
return 0;
}

how tailed recursion inside loop works?

I am trying to understrand recursion, and i am very new to recursion.
Considering the example given above there is a recursive call inside a for loop.
program is:
#include <iostream>
#include <string.h>
#define n 2
using namespace std;
int k = 0;
void nontailrec(int x) {
if(x == n) {
return;
}
for(int i = 0 ; i < n ; i++) {
cout<< i << " "<< x <<endl;
nontailrec(x+1);
}
}
int main() {
nontailrec(k);
return 0;
}
Now understanding the flow of the program what i figured out the flow is:
main();
nontailrec(0);
0 == 2 ?
<<0 0
nontailrec(1);
1 == 2 ?
<<0 1
nontailrec(2);
2 == 2 ?
return void
<<1 1
<<1 0
end of program
but the actual output is:
0 0
0 1
1 1
1 0
0 1
1 1
instead of
0 0
0 1
1 1
1 0
how the last two lines of output came, and what's the exact flow of program?
Recursive functions work exactly like non-recursive functions.
In particular, return does not return to the initial top-level call, only to the immediate caller.
That is, terminating a recursion is not like exiting a loop.
Supposing you had one unique function for each x, your program would be equivalent to this:
void nontailrec_2() {
}
void nontailrec_1() {
for(int i = 0 ; i < n ; i++) {
cout<< i << " "<< 1 <<endl;
nontailrec_2();
}
}
void nontailrec_0() {
for(int i = 0 ; i < n ; i++) {
cout<< i << " "<< 0 <<endl;
nontailrec_1();
}
}
int main()
{
nontailrec_0();
}
I'm sure you can follow the flow in this.

How to write 2D array with diagonally numbers? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
How to write in C++ 2D array with diagonally numbers for
n - size of array (width and height)
x - how many the same number in a row
c - how many numbers must be used
example for
n = 5
x = 2
c = 2
output is:
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0
My current code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n=0, x=0, c=0;
int temp_x=0,temp_c=-1;
cin >> n >> x >> c;
c--;
for(int i=0; i<n;i++){
for(int j=0; j<n;j++){
cout << ++temp_c;
temp_x++;
if(temp_x>x){
temp_x=0;
if(temp_c=c){
temp_c=-1;
}
}
}
cout << endl;
}
}
I will be grateful for your help. :)
But my code return incorrectly number :(
Are you trying to do this?
int main()
{
int n=0, x=0, c=0;
int temp_x=0,temp_c=0;
cin >> n >> x >> c;
c--;
for(int i=0; i<n;i++){
for(int j=0; j<n;j++){
if(temp_x<x)
{
temp_x++;
cout << temp_c << " ";
continue;
}
temp_c++;
temp_x=0;
if(temp_c>c)
{
temp_c=0;
}
cout << temp_c << " ";
temp_x++;
}
cout << endl;
}
}
Output:
5 2 2
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0
5 2 3
0 0 1 1 2
2 0 0 1 1
2 2 0 0 1
1 2 2 0 0
1 1 2 2 0
5 3 2
0 0 0 1 1
1 0 0 0 1
1 1 0 0 0
1 1 1 0 0
0 1 1 1 0
I'd like to propose another algorithm:
Run It Online !
#include <iostream>
#include <vector>
#include <numeric> // iota
using std::cout;
using std::endl;
void fill(const size_t n ///< size of array (width and height)
, const size_t x ///< how many the same number in a row
, const size_t c) ///< how many numbers must be used
{
// generate the sequence of possible numbers
std::vector<int> numbers(c);
std::iota(numbers.begin(), numbers.end(), 0);
//std::vector<int> all(n * n); // for storing the output, if needed
for (size_t i = 0, // element index
k = 0, // "number" index
elements = n * n; // the square matrix can also be viewed as a n*n-long, 1D array
i < elements;
k = (k + 1) % c) // next number (and the modulus is for circling back to index 0)
{
// print the number "x" times
for (size_t j = 0; j < x && i < elements; ++j, ++i)
{
// break the line every "n" prints
if ((i % n) == 0)
{
cout << endl;
}
//all[i] = numbers[k];
cout << numbers[k] << " ";
}
}
cout << endl;
}
int main()
{
fill(5, 2, 2);
}
Output for fill(5, 2, 2)
0 0 1 1 0
0 1 1 0 0
1 1 0 0 1
1 0 0 1 1
0 0 1 1 0