I have a probem with a class I'm writing.
It consists in a Matrix represented as an std::array of std::array. So the first array is a sort of container of columns or rows (this can be decided by the user).
The class keeps trave of this by using a boolean.
When I create a single instance of that all seems ok, the problem appears when i create an another instance: the second instance is ok, while in the first the boolean value changes.
I can't figure out the reason of this behaviour.
The problem is present only if i put the initializeToZero() method inside the default constructor, or also with the copy constructor. Moreover the 2 instance must have the same numberOfColumn, otherwise the problem does not appear.
I link you the most relevant part of the code:
#include <stdio.h>
#include <array>
using namespace std;
template <typename scalar,int numberOfRows,int numberOfColumns> class FullArrayMatrix {
bool onlyColumnBased; //if true the first array contains the columns
array<array<scalar, numberOfRows>, numberOfColumns> verticalMatrixArray;
array<array<scalar, numberOfColumns>, numberOfRows> horizontalMatrixArray;
// if onlyColumnBased is true tre programm considers only verticalMatrixArry, if false only horizontalMatrixArray
public:
///CONSTRUCTOR
FullArrayMatrix (bool forceColumnBased=true):onlyColumnBased(forceColumnBased){
initializeToZero();
} //default initializer
bool getOnlyColumnBased() const;
void print();
///OPERATOR
scalar & operator ()(int riga, int colonna);
};
//initializeToZero
template <typename scalar,int numberOfRows,int numberOfColumns>
void FullArrayMatrix<scalar,numberOfRows,numberOfColumns>::initializeToZero() {
for (int i=1; i<=numberOfRows; i++) {
for (int j=1; j<=numberOfColumns; j++) {
if ((*this)(i,j)) {
(*this)(i,j)=0;
}
}
}
}
//print
template<typename scalar,int numberOfRows,int numberOfColumns> void FullArrayMatrix<scalar, numberOfRows, numberOfColumns >::print(){
cout<<endl<<"--"<<endl;
if (getOnlyColumnBased()) {
for (int i=1; i< numberOfRows+1; i++) {
cout<<"|\t";
for (int j=1; j< numberOfColumns+1; j++) {
cout<<(*this)(i,j)<<"\t";
}
cout<<"|"<<endl;
}
}
else {
for (int i=1; i< numberOfColumns+1; i++) {
cout<<"|\t";
for (int j=1; j< numberOfRows+1; j++) {
cout<<(*this)(i,j)<<"\t";
}
cout<<"|"<<endl;
}
}
cout<<"--"<<endl;
}
template <typename scalar,int numberOfRows, int numberOfColumns> scalar & FullArrayMatrix<scalar,numeroRighe,numeroColonne>::operator ()(int row, int column){
if (getOnlyColumnBased()) {
return verticalMatrixArray[column][row];
} else {
return horizontalMatrixArray[row][column];
}
}
This is the main:
FullArrayMatrix<double, 10, 1> full1(true);
full1.print();
cout<<full1.getOnlyColumnBased()<<endl;
FullArrayMatrix<double, 10, 1> full2(true);
cout<<endl<<endl<<full1.getOnlyColumnBased()<<full2.getOnlyColumnBased()<<endl;
full1.print();
full1.initializeToZero();
full1.print();
And this is the output:
--
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
--
1
01
--
| 0 0 0 0 0 0 0 0 0 3.49057e-320 |
--
--
| 0 0 0 0 0 0 0 0 0 0 |
--
Thank you very much for any help!
It seems you have an off-by-one error ("there are two hard problems in computer science: naming things, cache coherency, and off-by-one errors"): C++ uses zero based arrays. You are accessing indices 1...numberOf... in your initializeToZero() method. As a result you'll have a buffer overrun which, apparently, results in some of your variables being overwritten.
After the first comment I discovered a stupid error, now the only problem is in the copy constructor. As described before it seems to change onlyColumnBased in the input matrix.
How can it change this value? inputMatrix is a const reference, isn't it?
The code is the following:
In the declaration:
FullArrayMatrix (const FullArrayMatrix<scalar,numeroRighe,numeroColonne> &inputMatrix,bool forceColumnBased=true);
In the implementation:
template <typename scalar,int numberOfRows, int numberOfColumns> FullArrayMatrix<scalar, numberOfRows, numberOfColumns >::FullArrayMatrix (const FullArrayMatrix<scalar, numberOfRows, numberOfColumns > &matriceInput,bool forceColumnBased):onlyColumnBased(forceColumnBased){
cout<<endl<<endl<<matriceInput.getOnlyColumnBased()<<onlyColumnBased;
if (!onlyColumnBased) {
for (int i=1; i< numberOfRows +1; i++) {
for (int j=1; j< numberOfColumns +1; j++) {
(*this)(i,j)=inputMatrix.horizontalMatrixArray[j-1][i-1];
}
}
} else {
for (int i=1; i< numberOfColumns +1; i++) {
cout<<endl<<"column "<<i<<" "<<inputMatrix.getOnlyColumnBased();
for (int j=1; j< numberOfRows +1; j++) {
cout<<endl<<"row "<<j<<" "<<inputMatrix.getOnlyColumnBased();
(*this)(i,j)=inputMatrix.verticalMatrixArray[i-1][j-1];
}
}
}
cout<<inputMatrix.getOnlyColumnBased();
}
I have put some cout to notice when onlyColumnBased changes and it seems to change in the 1st column, 3rd row.
This is the main:
FullArrayMatrix<double, 10, 1> full1(true);
full1.print();
FullArrayMatrix<double, 10, 1> full2(full1,true);
full1.print();
This is the output:
--
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
| 0 |
--
11
column 1 1
row 1 1
row 2 1
row 3 1
row 4 0
row 5 0
row 6 0
row 7 0
row 8 0
row 9 0
row 10 0
0
--
| 0 0 0 0 0 0 0 0 0 0 |
--
I really dont't have idea of the problem!
Related
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.
This my first post on stackoverflow so hopefully what I have posted adheres to correct guidelines/format on this forum site.
I am new to C++ so please bear with me. I am trying to implement a sudoku solver in C++ and 1 of my objectives is to read in a sudoku puzzle which is 9x9 grid, into an object array, specifically a 2D array and then display it's contents onto the command window.
The sudoku puzzle given is in the following format:
0 3 0 0 0 1 0 7 0
6 0 0 8 0 0 0 0 2
0 0 1 0 4 0 5 0 0
0 7 0 0 0 2 0 4 0
2 0 0 0 9 0 0 0 6
0 4 0 3 0 0 0 1 0
0 0 5 0 3 0 4 0 0
1 0 0 0 0 6 0 0 5
0 2 0 1 0 0 0 3 0
What I have in my header file (sudoku_header.h) is the following:
#pragma once
#ifndef SUDOKU_HEADER
#define SUDOKU_HEADER
#include <vector>
using namespace std;
class Cell
{
public:
friend istream& operator >>(istream &input, Cell& cellObject);
friend ostream& operator <<(ostream &output, Cell& cellObject);
bool ValueGiven();
void AssignCell(int num); // assigns a number to a cell on the puzzle board
void PopulateRows();
private:
int row, column, block; // triple context i.e. row, column and block
vector<int> candidateList; // holds a vector of all the possible candidates for a given cell
};
istream& operator >>(istream& input, Cell& cellObject)
{
input >> cellObject.row;
input >> cellObject.column;
return input;
}
ostream& operator <<(ostream& output, Cell& cellObject)
{
output << cellObject;
return output;
}
#endif
and this is whats inside my main.cpp file:
#include <iostream>
#include <fstream>
#include <ostream>
#include <istream>
#include "sudoku_header.h"
void PopulateRows(string filename)
{
Cell **cellObject;
const int row = 9;
const int column = 9;
cellObject = new Cell*[9];
for (int i = 0; i < 9; ++i)
{
cellObject[i] = new Cell[9];
for (int j = 0; j < 9; ++j)
{
cout << &cellObject[i][j] << endl;
}
}
}
int main()
{
PopulateRows("sudoku_puzzle.txt");
cout << "\n\nPlease enter a key to exit..." << endl;
cin.get();
return 0;
}
Now the above code will compile and work and will display the memory addresses for each of the cellObjects, but I want to be able to read in a sudoku puzzle, named "sudoku_puzzle.txt" and then display its contents in a 9x9 grid fashion.
Can anyone possibly point me in the right direction or even show me how?
First, since the input is line oriented, I'd use std::getline
for each line. The traditional approach after that would be to
use std::istringstream to parse the values in the line, but
for something this simple (where each digit has a fixed
location, and the actual values are only a single digit), it's
probably just as simple to extract the values directly from the
string: character - '0' for the respective character. (Output
is similar: cellValue + '0', inserting additional spaces where
necessary.)
I'd also forgo the Cell class, and simply use an
std::vector<int> grid(81); for the entire grid. It's probably
easier to keep all of the relevant information in a Grid
class. This depends, and both solutions are viable. But
I certainly wouldn't keep row, column and block in
Cell, since they aren't characteristics of the cell, but
rather of where it is placed in the grid. And I wouldn't keep
candidateList in the cell either: at any given moment, the
cell has only one value, and the candidate list is only
relevant for the cell(s) you're currently looking at, and is
best implemented as a local variable.
Result:
. 3 . | . . 1 | . 7 .
| |
6 . . | 8 . . | . . 2
| |
. . 1 | . 4 . | 5 . .
| |
--------- ----------- ---------
| |
. 7 . | . . 2 | . 4 .
| |
2 . . | . 9 . | . . 6
| |
. 4 . | 3 . . | . 1 .
| |
--------- ----------- ---------
| |
. . 5 | . 3 . | 4 . .
| |
1 . . | . . 6 | . . 5
| |
. 2 . | 1 . . | . 3 .
Code.. The printing algorithm is from my own sudoku solver..
#include <vector>
#include <iostream>
#include <fstream>
class Puzzle
{
private:
unsigned short Cells[9][9];
char BlankChar;
public:
Puzzle(const char* FilePath, char BlankChar = '.');
friend std::ostream& operator << (std::ostream& os, const Puzzle& p);
};
Puzzle::Puzzle(const char* FilePath, char BlankChar) : Cells(), BlankChar(BlankChar)
{
std::fstream fs(FilePath, std::ios::in);
if (fs.is_open())
{
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 9; ++j)
{
fs >> Cells[j][i];
}
}
fs.close();
}
}
std::ostream& operator << (std::ostream &os, const Puzzle &p)
{
for (int I = 0; I < 9; ++I)
{
for (int J = 0; J < 9; ++J)
{
if (J == 3 || J == 6)
{
os << "| ";
}
if (p.Cells[J][I] == 0)
os << p.BlankChar << " ";
else
os << p.Cells[J][I] << " ";
}
os << "\n";
if (I != 8)
{
os << "\t |\t |\n";
}
if (I == 2 || I == 5)
{
os << "--------- ----------- ---------";
os << "\n";
os << "\t |\t |\n";
}
}
return os;
}
int main()
{
std::cout << Puzzle("sudoku_puzzle.txt");
}
I'm trying to read from file (myfile.in) a 2D array. Rows and cols are given.
myfile>>n>>m; //rows and cols
for(int i = 0; i < n; i++) {
for(int j =0; j < m; j++) {
myfile>>tab[i][j];
cout<<tab[i][j]<<" ";
}
cout<<endl;
}
and the output on the screen is as it should be (as it is in file):
1 0 0 0 1 0 1
0 1 1 1 1 0 0
0 0 1 0 1 1 0
0 1 0 0 1 0 0
0 1 0 0 0 1 1
1 1 1 1 0 0 0
0 1 0 0 0 1 1
after that i tryied to print the array separately.
for(int i = 0; i < n; i++) {
for(int j =0; j < m; j++) {
cout<<tab[i][j]<<" ";
}
cout<<endl;
}
and the output is:
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
actually it's showing the last row, why?
According to your comment, you are actually initializing tab to be tab[0][0]. I don't know how come the compiler allows that, but the important thing is that you're writing outside your array bounds, triggering undefined behavior.
Try dynamically allocating your array after reading in n and m:
int n, m;
file >> n >> m;
int **tab = new int* [n];
for(size_t i = 0; i < n; ++i)
{
tab[i] = new int[m];
}
This way you'll always be sure to allocate only as much memory as you need.
Also, don't forget to delete the array when you're done:
for(size_t i = 0; i < n; ++i) delete[] tab[i];
delete[] tab;
As you can see this method tends to add a bit too much unnecessary complexity. An elegant alternative would be using a container such as a std::vector<std::vector<int>>:
using namespace std;
vector<vector<int>> tab;
for(int i = 0; i < n; ++i) {
vector<int> current_row;
for(int j = 0; j < m; ++j) {
int buff;
file >> buff;
current_row.push_back(buff);
}
tab.push_back(current_row);
}
int n=0, m=0; int tab[n][m];
This is not legal C++ for two reasons:
Dimensions of an array must be constant expressions. n and m are not.
You are creating an array of 0 size.
If the constant-expression (5.19) is present, [...] its value shall be greater than zero.
Your compiler is accepting it because it has extensions that accept both of these. Nonetheless, your array has size 0 and so it has no elements. Anything you attempt to write to it will be outside the bounds of the array.
Reading myfile>>n>>m; doesn't automatically change the size of the array. You already declared it as being size 0. Nothing you do will change that.
Instead, you'd be much better off using a standard library container, such as a std::vector, which can change size at run-time. Consider:
myfile >> n >> m;
std::vector<std::vector<int>> tab(n, std::vector<int>(m));
You can then use this tab object in exactly the same way as you have above.
This is some basic code for an array I'm writing. I need to fill all slots (14) of the array with 4, and then write a loop that will replace the slots 6 and 13 with 0. I am a beginner and have not learned vectors yet, just basic programming material.
const int MAX = 14;
int main ()
{
board ();
cout<<endl;
{
int i;
int beadArray[MAX] = {4};
for (i = 0; i < MAX; i++)
{
beadArray[i] = -1;
}
for (i = 0; i < MAX; i++)
{
cout<<i<<"\t";
}
}
cout<<endl;
system("pause");
return 0;
}
#include <iostream>
#include <cstdlib>
using namespace std;
int main(){
//this constant represents the size we want our array to be
//the size of an array must be determined at compile time.
//this means you must specify the size of the array in the code.
const unsigned short MAX(14);
//now we create an array
//we use our MAX value to represent how large we want the array to be
int beadArray[MAX] = {4};
//now our array looks like this:
//+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//| 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
//+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//but you want each index to be filled with 4.
//lets loop through each index and set it equal to 4.
for (int i = 0; i < MAX; ++i){
beadArray[i] = 4;
}
//now our array looks like this:
//+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//| 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
//+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//to set slots 6 and 13 equal to 0, it is as simple as this:
beadArray[6] = 0;
beadArray[13] = 0;
//careful though, is that what you wanted?
//it now looks like this:
//+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//| 4 | 4 | 4 | 4 | 4 | 4 | 0 | 4 | 4 | 4 | 4 | 4 | 4 | 0 |
//+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//this is because the [index number] starts at zero.
//index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
// | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
//print out your array to see it's contents:
for (int i = 0; i < MAX; i++){
cout << beadArray[i] << " ";
}
return EXIT_SUCCESS;
}
you could do something like this
int beadArray[14];
for(int i=0;i<14;i++){
beadArray[i]=4;
}
beadArray[6]=0;
beadArray[13]=0;
or
int beadArray[14];
for(int i=0;i<14;i++){
if(i==6 || i==13)
beadArray[i]=0;
else
beadArray[i]=4;
}
I realize that if I want "valArray" to populate to the right of "COLUMN 0,0" I should put "[j][1]", however, I keep getting an error when I do that.
OUTPUT:----------------------------------------------------------------------------------------------------------------------------------------------------
55 0 0 0 0 0 0 0 0 0 0 0 0 -------THIS IS ROW 1------------------------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 10 10 11 ----THIS IS ROW 2-----------------------------------------------------------------------------------------------
77 0 0 0 0 0 0 0 0 0 0 0 0 -------THIS IS ROW 3------------------------------------------------------------------------------------------------
88 0 0 0 0 0 0 0 0 0 0 0 0 -------THIS IS ROW 4-----------------------------------------------------------------------------------------
Please advise how to populate correctly, thanks.
#include <iostream>
#include <vector>
#include <Windows.h>
#include <algorithm>
using namespace std;
int main()
{
int typeArray[4] = {55,66,77,88};
int valArray[13] = {1,2,3,4,5,6,7,8,9,10,10,10,11};
// for vector: 4 = LENGTH or NUMBER of ROWS; 13 = WIDTH or NUMBER of COLUMNS;
// 0 = VALUE all cells are initialized to
vector< vector <int> > myVector(4, vector<int> (13,0));
for (int i = 0; i < 4; i++)
{
myVector[i][0] = typeArray[i];
for (int j = 0; j < 13; j++)
{
myVector[1][J] = valArray[j];
}
}
// print vector to screen with 2 ROWS, 3 COLUMNS
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 13; j++)
{
cout << myVector[i][j] << ' ';
}
cout << '\n';
}
system("Pause");
return 0;
}
One problem is that the loops should be until sizeof(typeArray)/sizeof(typeArray[0]) instead of sizeof(typeArray). Sizeof simply gives you the size of the array in bytes. You need to divide that by the size of each element in order to get the number of elements.
As for how to combine the arrays, I think you have the right idea with the for loop, and simply manually assigning the values.
example psuedo code:
for each element in typeArray
myVector[i][0] = typeArray[i];
myVector[i][1] = valArray[i];
The reason your code is not working is because you are not assigning any values to myVector.
Assuming typeArray and valArray are of the same length and you want to place each in a column, try something like this
for (int j = 0; j < sizeof(typeArray)/sizeof(int); j++)
{
myVector[j][0] = typeArray[j];
myVector[j][1] = valArray[j];
}