So I'm doing a puzzle game and I came to a problem. My Board will get scrambled later on in the program. I want to make a copy of it before it gets scrambled, to use it in the win-condition for my game. My Idea is to compare the copied board to the scrambled board every time the user moves a tile to see if they succeded (won) or not. But I'm a bit unsure how to do the copy constructor for the board. Here is what I have done(doesn't work as it's supposed to do).
Board::Board(int userInput)
{
this->gameSize = userInput;
int zeroPos[2] = { 0, 0 };
SetTileNumbers();
}
void Board::SetTileNumbers()
{
const int sizeOfGame = gameSize; //Size given from user when the board was created.
int tileNumber = 0; //The value given to each Tile.Number.
int row, column;
boardOfTiles = new Tile* [sizeOfGame];
for (int i = 0; i < sizeOfGame; i++)
{
boardOfTiles[i] = new Tile [sizeOfGame]; //The doublepointer is given an additional dimension
}
for (row = 0; row < sizeOfGame; row++)
{
for (column = 0; column < sizeOfGame; column++)
{
boardOfTiles[row][column].number = tileNumber; //Loops that goes through the entirety to instantiate the board of tiles.
tileNumber++;
}
}
}
void Board::SetTileNumbers(const Board& copy)
{
const int sizeOfGame = copy.gameSize;
int row , column;
boardOfTiles = new Tile*[sizeOfGame];
for (int i = 0; i < sizeOfGame; i++)
{
boardOfTiles[i] = new Tile[sizeOfGame];
}
for (row = 0; row < sizeOfGame; row++)
{
for (column = 0; column < sizeOfGame; column++)
{
boardOfTiles[row][column].number = copy.boardOfTiles[row][column].number;
}
}
}
I hope this does not sound off-topic, but copy-constructor aside, I think you might have a different problem: the way you decide on a solution is very inefficient. You waste cpu time and you waste memory.
For every step to compare two NxN boards is about as ineffciciet as it gets. You can try a different approach: assign a number to each position on the board and you know that the solution is to have the numbers sorted in a particular order.
For a 3x3 board, 'THE' solution would look like:
1 2 3
4 5 6
7 8 9
Furthermore, a 2d array is stored in memory as a continuous array, you you can treat the solution as an array:
1 2 3 4 5 6 7 8 9
Any other arrangement will not represent an solution.
Checking weather an array is sorted is a much easier problem to solve. Worst case scenario you are still looking at O(n^2) to check if the array is sorted but without the memory overhead. Plus I'm sure you can figure out a more efficient algorithm to check if the array is sorted.
I hope this helps...
Related
I am translating some algorithm into C++ (which I wrote in R and already translated into C++ with raw pointers). The problem with the original C++ translation is that it crashes for large matrices and suffers from memory leaks (but is approx 1000 times faster than R which is amazing)... So i try again with vector. Basically I have a matrix with zeroes and ones and want to replace the ones by a number indicating a group.
A group would be defined by horizontally or vertically connected one-entries.
I do this by building up a matrix of pointers and change the group indices they point to during the process.
The code below is an excerpt.
vector<int> groups(vector<int> matrix, int nrow, int ncol) {
vector<connection> connections;
vector<int *> pointersToIndices;
int zeroGroupIndex = 0;
int* O = &zeroGroupIndex;
int currentN = 1;
int size = nrow * ncol;
vector<int **> pointerMatrix;
for (int i = 0; i < size; i++) {
int** OO = &O;
pointerMatrix.push_back(OO);
}
int col, row, index, leftIndex, upperleftIndex, upperIndex;
for (col = 0; col < ncol; col++) {
for (row = 0; row < nrow; row++) {
index = nrow * col + row;
if (matrix[index] != 0) {
upperIndex = nrow * col + row - 1;
leftIndex = nrow * (col - 1) + row;
if (row == 0 || matrix[upperIndex] == 0) {
currentN++;
matrix[index] = currentN;
pointersToIndices.push_back(&(matrix[index]));
// I assume the following does not do what i intend
pointerMatrix[index] = &pointersToIndices.back();
}
else pointerMatrix[index] = pointerMatrix[upperIndex];
if (col != 0 && matrix[leftIndex] != 0) *pointerMatrix[index] = *pointerMatrix[leftIndex];
}
}
}
....
....
Now the problem is that the assignments dont work as I want them to. Especially the line
pointerMatrix[index] = &pointersToIndices.back();
seems to fail, since at the end of the loop all elements of pointerMatrix point to the last entry of pointersToIndices and not the correct one.
I hope I could clarify the problem.
Any suggestions?
Thank you very much.
The problem is that pointerToIndices will eventually reallocate when it has to grow (after a number of push_backs). This invalidates pointers to its elements (such as those taken and stored in the line after the comment), so using them later on is undefined behavior.
I have not fully understood your algorithm, but either ensure that pointersToIndices does not reallocate (by reserving enough space beforehand) or refrain from using pointers to its elements. (Or change your algorithm).
iam trying to write a function that shifts rows in c++
for example
1 2 3
4 5 6
7 8 9
i want to shift it by one so the result is
7 8 9
1 2 3
4 5 6
the parameters is
void Matrix:: rowShift(const int shiftSize){}
here is the class
class Matrix {
private:
std::string type;
int row, col;
double **array;
void rowShift(const int shiftSize);
here is the constructor
Matrix::Matrix(int rows, int cols, std::string matType) {
type = matType;
row = rows;
col = cols;
array= new double*[row];
for (int i = 0; i < row; ++i)
array[i] = new double[col];
for (int i = 0; i < rows; i++)
for (int j = 0; j<cols; j++)
array[i][j] = 0;
}
any ideas iam new to see and i have a problem iam not used to the syntax either
I am new to C++ and I am not used to the syntax either
First things first, if you are new to the language you should take some time to read up on the basics before you just start writing code. There are many great books to get you started. I would recommend something like this introduction to programming in C++ written by the creator of the language.
Programming: Principles and Practice Using C++ (Bjarne Stroustrup)
I am trying to write a function that shifts rows in C++
So you have a two dimensional array (matrix) that you want to shift all rows down, and the old bottom row becomes the new top row. This seems like it might be your homework assignment loay. Is it your homework? If it is, please tag it as such in the future to be honest with yourself and others. I want you to stop reading my answer to your question now, go get that book and read it cover to cover. Once do that come back and check my answer.
Now that you're familiar with C++ I'll also assume you are familiar with the the standard template library and container objects such as std::vector.
here is the constructor
Now that you're familiar with C++, you know that you can use member initializer lists for your constructor arguments. This means you don't have to initialize them in the body of the constructor! I'm going to leave out your std::string matType variable because it's not used anywhere in the code you provided. I recommend using a nested std::vector to hold your matrix data as opposed to a C style array. The std::vector class will do all your memory management for you (new double[col] will not be necessary). Here we have defined the class private member variable mMatrix to be a std::vector of rows and columns std::vector< std::vector<double> > mMatrix;
Matrix( const size_t rows,
const size_t cols ) :
mRows(rows),
mCols(cols),
mMatrix(rows, std::vector<double>(cols)) {
init();
}
The Matrix::init() function will populate your matrix with default values incrementing from 1 to n. We do this using the concepts you read up on like std::iterator.
void init()
{
std::vector< std::vector<double> >::iterator row;
std::vector<double>::iterator col;
double seedVal(1.0);
for (row = mMatrix.begin(); row != mMatrix.end(); ++row)
{
for (col = row->begin(); col != row->end(); ++col)
{
*col = seedVal;
seedVal++;
}
}
}
Now I'm going to assume that you'll want to print the values of your matrix to verify that the shift down operation has worked. You can print the matrix using nested for loops very similar to the way we initialized the values earlier. This time we can use ::const_iterator since when we print, we are making a guarantee that we are not modifying the contents. We also use formatting flags from #include <iomanip> like std::setfill(' ') and std::setw(6) to get the spacing and formatting to look nice.
void print()
{
std::vector< std::vector<double> >::const_iterator row;
std::vector<double>::const_iterator col;
for (row = mMatrix.begin(); row != mMatrix.end(); ++row)
{
for (col = row->begin(); col != row->end(); ++col)
{
std::cout << std::setfill(' ') << std::setw(6) << *col;
}
std::cout << std::endl;
}
}
Now let's talk about the real reason you're here. The method to down shift the entire matrix (which I think should be a public method of the Matrix class so that it can be accessed by anyone). First, whenever you shift the contents of an array (vector) you must loop in the opposite direction of the shifting. In our case, we should invert the direction of our outer loop over each row. We also do NOT want to overwrite the contents of our rows without saving what was there before. We can accomplish this with a temporary variable that will, you guessed it, temporarily hold the old value while we shift the new one. Here is the method that will down shift all elements of the matrix, as long as we have at least one row to work with.
void shiftDown()
{
if (mRows > 0)
{
for (size_t i = mRows - 1; i-- > 0; )
{
for (size_t j = 0; j < mCols; ++j)
{
double temp = mMatrix[i+1][j];
mMatrix[i+1][j] = mMatrix[i][j];
mMatrix[i][j] = temp;
}
}
}
}
There now you have a self contained Matrix class with a method that will shift each row down and wrap around the top row. For bonus points, you can play with variations of this nested loop to implement methods like shiftUp(), shiftLeft(), and shiftRight().
I am trying to find the number of ways possible to set 5 queens on a chess board without them being able to attack each other. I have succeeded to find the first set. The problem is how would I be able to find the next set of positions for 5 queens. The procedure in my program is like this:
Generate a vector of disallowed positions based on the current queens on the board
Loop through all the positions on the board
Check if the current position is one of the disallowed positions on the board
If it is not, return the position, add it to the vector of queens on the board and begin the process again
Continue until there is no more position available i.e. all the remaining positions are disallowed
#include <iostream>
#include <vector>
using namespace std;
const int BSIZE = 8;
char chessBoard[BSIZE][BSIZE];
struct qPos
{
qPos() : h(0), v(0), found(true) {}
int h; //horizontal pos
int v; //vertical pos
bool found; //if position is available
};
qPos findNextQPos(vector<qPos> Qs);
void fillBoard(vector<qPos> Qs);
void print();
vector<qPos> generateDisallowed(vector<qPos> Qs);
bool isDisallowed(qPos nextPos, vector<qPos> disallowedPos);
int main(int argc, char **argv){
vector<qPos> QsOnBoard; //Position of all the queens on board
qPos nextQ; //next possible position
while (nextQ.found)
{
nextQ = findNextQPos(QsOnBoard);
if (nextQ.found)
{
QsOnBoard.push_back(nextQ); //If the nextQ is available i.e. not disallowed, add it to the queens vector
}
}
fillBoard(QsOnBoard); //Fill the board with queens positions
print(); // print the board
return 0;
}
qPos findNextQPos(vector<qPos> Qs) {
// Generate disallowed positions based on all the queens on board
vector <qPos> disallowedPos = generateDisallowed(Qs);
qPos nextQ;
for (size_t i = 0; i < BSIZE; i++)
{
for (size_t j = 0; j < BSIZE; j++)
{
nextQ.h = i;
nextQ.v = j;
if (!isDisallowed(nextQ, disallowedPos)) { //Check if next possible position is a disallowed position
//cout << "Next available:\n" << nextQ.h << ", " << nextQ.v << endl;
return nextQ; // if it is avaible return the position, break the loop
}
}
}
nextQ.found = false; // No available position is found to return, found is set to false, return the position
return nextQ;
}
Rest of the source code where I have the other functions such as generate disallowed and isDisallowed and etc is on this pastebin. I thought it would not be really related to the question and the code here should not be too long.
The result of the first set looks like this:
So how should I continue in order to be able to find all solution sets? This is where I get stuck.
First, combine these two loops into one:
for (size_t i = 0; i < BSIZE; i++)
{
for (size_t j = 0; j < BSIZE; j++)
{
Instead:
for (size_t n = 0; n < (BSIZE * BSIZE); ++n)
{
size_t i = n % BSIZE;
size_t j = n / BSIZE;
Now your function can easily take a starting n. To find the "next" solution, simply remove the last queen (noting its position) and call FindNextQPos, telling it to start at the position one past that queen. If that queen is already at the last position, go back and remove another queen.
If you find no solution, do the same thing as if you do find a solution. Remove the last queen and call FindNextQPos, again starting one past the position of the queen you removed.
When you have no queens to remove, you are done.
You can do this with a single "continue" function. You can call this function whether you found a solution or found no solution. Its logic is:
Find the last queen. If there's no last queen, stop. We are done.
Note its position. Remove it.
Call FindNextQPos starting at the position one past the position we noted. If we placed a queen, keep trying to place more queens starting at position zero until we find a solution or can't place a queen.
If we found a solution, output it.
Go to step 1.
OK guys, I have this problem where I have to print the number of the rows of a matrix that are composed from the same set of numbers as the number of a row I input. For example:
Input:4 5 3
1 2 2 3
2 4 1 3
1 1 1 3
3 1 1 2
3 1 3 2
Output:0 4
Note that we first input the number of the columns,then the rows and then the row k.
I get on the input only the 0 and can't figure why? I think my logic is ok, but who knows I'm new to programing. So if you could tell me where my mistake is that would be great. Here is my code:
#include<iostream>
using namespace std;
int const l=50;
int main ()
{
int n,m,k,br=0,br2=0;
bool t1=false;
bool t2=false;
cin>>n>>m>>k;
int a[l][l];
for(int i=0;i<m;i++)
{
for (int j=0;j<n;j++)
cin>>a[i][j];
}
for(int i=0;i<m;i++)
{
for(int p=0;p<n;p++)
{
for(int j=0;j<n;j++)
{
if(a[k][p]==a[i][j])
{
br++;
}
}
if(br==0)
{
t1=true;
}
br=0;
}
for(int j=0;j<n;j++)
{
for(int p=0;p<n;p++)
{
if(a[i][j]==a[k][p])
{
br2++;
}
}
if(br2==0)
{
t2=true;
}
br2=0;
}
if(t1==false && t2==false && i!=k)
{
cout<<i<<" ";
}
}
}
Here is my solution for you. From a high level viewpoint, the basic task is that you want to do a bunch of comparisons between members within an array. I'm not really sure of your code, so here is my own unique solution for you.
step 1 - find all the members of the array row or column that you are interested in, and add them to your list. if you know the sizes of everything than use an array, if not then use a vector. lets call this 1d array memberlist[]
step 2 - loop through memberlist[] and search for each member of memberlist within a every row/column. For this example lets say you are interested in rows, not that there is any real difference.
step 3 - make yet another int array which we will call matchlist[]. matchlist should have a length equal to the number of rows in the array you are comparing with. initialize every value in matchlist to zero.
step 4 - every time you have a hit from the memberlist[] comparing to the rows, add 1 to the corresponding row's score sheet in matchlist.
at the end of the first loop, you should have checked every row for every member of the row you are trying to match it with, and you will get a score for each one contained within matchlist[]. choose the ones with the score you can accept, whether or not thats the full length of memberlist[] or maybe 3 out of 4.
int rowsize = 5;
int columnsize = 5;
//step 1
testarray[rowsize][columnsize] = {whatever you want};
//choose row
cin>>row;
int i;
int j;
int memberlist[rowsize] = {0};
for(i = 0; i < rowsize; i++){
memberlist[i] = testarray[i][columnsize]
}
//memberlist is programmed
int tempid;
int membercounter;
int tempmember;
int matchlist[columnsize];
// step2 & 3
for (membercounter = 0; membercounter < rowsize; membercounter++){
tempmember = memberlist[membercounter];
for(i=0;i<columnsize;i++){
for (j=0;j<rowsize;j++)
tempid = temparray[j][i];
//step 4
if ( tempid == tempmember){matchlist[i]++;}
}
}
}
// use some code to cout the columns based on the matchlist score
for (i=0; i< columnsize; i++)
{ printf( "matchlist[%d] has a score of %d \n", i,matchlist[i]);}
//or whatever you want.
I hope this helps. Cheers.
I have 2 arrays called xVal, and yVal.
I'm using these arrays as coords. What I want to do is to make sure that the array doesn't contain 2 identical sets of coords.
Lets say my arrays looks like this:
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
Here I want to find the match between xVal[0] yVal[0] and xVal[1] yVal[1] as 2 identical sets of coords called 1,1.
I have tried some different things with a forLoop, but I cant make it work as intended.
You can write an explicit loop using an O(n^2) approach (see answer from x77aBs) or you can trade in some memory for performance. For example using std::set
bool unique(std::vector<int>& x, std::vector<int>& y)
{
std::set< std::pair<int, int> > seen;
for (int i=0,n=x.size(); i<n; i++)
{
if (seen.insert(std::make_pair(x[i], y[i])).second == false)
return false;
}
return true;
}
You can do it with two for loops:
int MAX=4; //number of elements in array
for (int i=0; i<MAX; i++)
{
for (int j=i+1; j<MAX; j++)
{
if (xVal[i]==xVal[j] && yVal[i]==yVal[j])
{
//DUPLICATE ELEMENT at xVal[j], yVal[j]. Here you implement what
//you want (maybe just set them to -1, or delete them and move everything
//one position back)
}
}
}
Small explanation: first variable i get value 0. Than you loop j over all possible numbers. That way you compare xVal[0] and yVal[0] with all other values. j starts at i+1 because you don't need to compare values before i (they have already been compared).
Edit - you should consider writing small class that will represent a point, or at least structure, and using std::vector instead of arrays (it's easier to delete an element in the middle). That should make your life easier :)
int identicalValueNum = 0;
int identicalIndices[4]; // 4 is the max. possible number of identical values
for (int i = 0; i < 4; i++)
{
if (xVal[i] == yVal[i])
{
identicalIndices[identicalValueNum++] = i;
}
}
for (int i = 0; i < identicalValueNum; i++)
{
printf(
"The %ith value in both arrays is the same and is: %i.\n",
identicalIndices[i], xVal[i]);
}
For
int xVal[4] = {1,1,3,4};
int yVal[4] = {1,1,5,4};
the output of printf would be:
The 0th value in both arrays is the same and is: 1.
The 1th value in both arrays is the same and is: 1.
The 3th value in both arrays is the same and is: 4.