shifting rows in 2d array matrix - c++

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().

Related

2-D vector Size

In C++ , I Made A Code That has A 2D Vector in it and Users are Required to give The inputs In 2D vector . I find It difficult To find The no. of rows in 2 vector with the help of size function.
#include <bits/stdc++.h>
#include <vector>
using namespace std;
int diagonalDifference(vector<vector<int>> arr)
{
int d = arr[0].size();
cout << d;
return 0;
}
int main()
{
int size;
cin >> size;
vector<vector<int>> d;
for (int i = 0; i < size; i++)
{
d[i].resize(size);
for (int j = 0; j < size; j++)
{
cin >> d[i][j];
}
}
cout << diagonalDifference(d);
}
The Output Should BE No. Rows , But it is coming NULL
Here
vector<vector<int>> d;
for (int i = 0; i < size; i++)
{
d[i].resize(size);
//...
d is a vector of size 0 and accessing d[i] is out of bounds. You seem to be aware that you first have to resize the inner vectors, but you missed to do the same for the outer one. I dont really understand how your code can run as far as printing anything for arr[0].size(); without segfaulting. Anyhow, the problem is that there is no element at arr[0].
But first, Look at your function argument -> is a copy of your vector ,use (vector<> & my vec) to avoid the copying mechanism of vector class (copy constructor for instance) cause if you put there your vector as a parameter and u will make some changes inside the function brackets you will not see any results ( if you dont wanna change your primary vector from function main, keep it without changes).
Secondly, look at code snippet pasted below.
std::vector<std::vector<typename>> my_vector{};
my_vector.resize(width);
for (size_t i = 0; i < my_vector.size(); ++i)
{
my_vector[i].resize(height);
}
It gives you two dimensional vector
Operator[] for vector is overloaded and you have to use my_vector[0].size() just
my_vector[1].size() and so on ! I recommend for that displaying the size by kind of loops given in c++ standards
Regards!

two dimensional vector matrices addition

vector<vector<int>> AsumB(
int kolumny, vector<vector<int>> matrix1, vector<vector<int>> matrix2) {
vector<vector<int>>matrix(kolumny);
matrix = vector<vector<int>>(matrix1.size());
for (int i = 0; i < kolumny; ++i)
for (int j = 0; i <(static_cast<signed int>(matrix1.size())); ++i)
matrix[i][j] = matrix1[i][j] + matrix2[i][j];
return matrix;
}
Please tell me what I don't understand and help me solve this problem
because for 1dimensional vector this kind of description would work;
What about
vector<vector<int>> AsumB(vector<vector<int>> const & matrix1,
vector<vector<int>> const & matrix2) {
vector<vector<int>> matrix(matrix1);
for (std::size_t i = 0U; i < matrix.size(); ++i)
for (std::size_t j = 0U; j < matrix[j].size(); ++j)
matrix[i][j] += matrix2[i][j];
return matrix;
}
?
Unable to reproduce, and OP's reported compiler error doesn't look like it matches the code, so the problem is probably somewhere else.
However, there is a lot wrong here that could be causing all sorts of bad that should be addressed. I've taken the liberty of reformatting the code a bit to make explaining easier
vector<vector<int>> AsumB(int kolumny,
vector<vector<int>> matrix1,
vector<vector<int>> matrix2)
matrix1 and matrix2 are passed by value. There is nothing wrong logically, but this means there is the potential for a lot of unnecessary copying unless the compiler is very sharp.
{
vector<vector<int>> matrix(kolumny);
Declares a vector of vectors with the outer vector sized to kolumny. There are no inner vectors allocated, so 2D operations are doomed.
matrix = vector<vector<int>>(matrix1.size());
Makes a temporary vector of vectors with the outer vector sized to match the outer vector of matrix1. This temporary vector is then assigned to the just created matrix, replacing it's current contents, and is then destroyed. matrix still has no inner vectors allocated, so 2D operations are still doomed.
for (int i = 0; i < kolumny; ++i)
for (int j = 0; i < (static_cast<signed int>(matrix1.size())); ++i)
i and j should never go negative (huge logic problem if they do), so use an unsigned type. Use the right unsigned type and the static_cast is meaningless.
In addition the inner for loop increments and tests i, not j
matrix[i][j] = matrix1[i][j] + matrix2[i][j];
I see nothing wrong here other than matrix having nothing for j to index. This will result in Undefined Behaviour as access go out of bounds.
return matrix;
}
Cleaning this up so that it is logically sound:
vector<vector<int>> AsumB(const vector<vector<int>> & matrix1,
const vector<vector<int>> & matrix2)
We don't need the number of columns. The vector already knows all the sizes involved. A caveat, though: vector<vector<int>> allows different sizes of all of the inner vectors. Don't do this and you should be good.
Next, this function now takes parameters by constant reference.. With the reference there is no copying. With const the compiler knows the vectors will not be changed insode the function and can prevent errors and make a bunch of optimizations.
{
size_t row = matrix1.size();
size_t is an unsigned data type guaranteed to be large enough to index any representable object. It will be bg enough and you don't have to worry about pesky negaitve numbers. Also eliminates the need for any casting later.
if (!(row > 0 && row == matrix2.size()))
{
return vector<vector<int>>();
}
Here we make sure that everyone agrees ont he number of rows inviolved and return an empty vector if they don't. You could also throw an exception. The exception may be a better solution, but I don't know the use case.
size_t column = matrix1[0].size();
if (!(column > 0 && column == matrix2[0].size()))
{
return vector<vector<int>>();
}
Dowes the same as above, but makes sure the number of columns makes sense.
vector<vector<int>> matrix(row, vector<int>(column));
Created a local row by column matrix to store the result. Note the second parameter. vector<int>(column) tells the compiler that all row inner vectors will be initialized to a vector of size column.
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < column; ++j)
{
Here we simplified the loops just a bit since we know all the sizes.
matrix[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return matrix;
The compiler has a number of tricks at its disposal to eliminate copying matrix on return. Look up Return Value Optimization with your preferred web search engine if you want to know more.
}
All together:
vector<vector<int>> AsumB(const vector<vector<int>> & matrix1,
const vector<vector<int>> & matrix2)
{
size_t row = matrix1.size();
if (!(row > 0 && row == matrix2.size()))
{
return vector<vector<int>>();
}
size_t column = matrix1[0].size();
if (!(column > 0 && column == matrix2[0].size()))
{
return vector<vector<int>>();
}
vector<vector<int>> matrix(row, vector<int>(column));
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < column; ++j)
{
matrix[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return matrix;
}

copy constructor [array] C++

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...

Initializing a member vector<vector<int>> in the constructor value-by-value

I have a class that should generate a 2D vector of ints (in the range of 0-1) that I want to use as a map (called matrix).
class generator
{
public:
void draw(void);
void iterate(void);
generator();
~generator();
private:
vector<vector<int>> matrix;
};
In the constructor I want to fill the matrix with random data:
vector<vector<int>> matrix(height, vector<int>(width));
for (int i = 0; i < height; i++){
for (int j = 0; j < width; j++) {
matrix[i][j] = rand() % 2;
}
}
But I get a read acess violation.
Thank you for your time and effort.
DEPRECATED UPDATE:
I tried using the member function .data() to retrieve the pointer to the data and accessing it directly
ptr = matrix[i][j].data();
*ptr = rand() % 2;
But the result doesn't differ. I'm fairly convinced that this isn't about how I want to access the vector but how I set it up.
UPDATE 2:
The correction provided below does result in the vector being filled as intended. When trying to
cout << matrix[i][j];
in the draw member function I get a read-acess-violation again.
UPDATE 3:
As suggested I checked when exactly this error happens. It happens on the very first try do print out the first integer at matrix[0][0]. The value returned is 0x8. Important: If not replaced by a constant matrix.size() already causes the error.
UPDATE 4:
This is basically my draw()
void generator::draw() {
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[i].size(); j++) {
cout << matrix[i][j];
}
cout << endl;
}
}
The original source has been updated to reflect the current one.
UPDATE 4:
Slightly cut source code at http://pastebin.com/83vrDJWZ
UPDATE 5:
One more simple mistake on my part has been resolved in the comments. Problem is silved. Thank you all.
Looks like the problem is an invalid pointer due to:
vector<vector<int>*> matrix;
You have a vector of pointers to vector of int, but you never actually allocate the inner elements.
Instead use:
vector<vector<int>> matrix;
And during the initialization steps:
matrix[i].resize(width); // instead of: matrix[i]->resize(width);
Actually, you could simplify it a bit:
std::vector<std::vector<int>> matrix(height, std::vector<int>(width));
Still have to iterate to fill the data, though.

C++ Checking for identical values in 2 arrays

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.