Swapping two rows in a matrix - c++

I am having a problem in swapping two rows in a matrix that is a 2D-dynamic array. I wanted to know if there is a function to use directly or if there is none I would like to know how to make one. Thanks in advance.
Here is how I made the dynamic array:
int **ptrMatrix = new int*[row];
for (int i = 0; i < row; i++)
ptrMatrix[i] = new int[column];

I found the solution ... it is done simply by making a temporary variable (X) and appling the following code
for (int i=0;i<columns;i++)
{
X=matrix[row1-1][i];
matrix[row1-1][i]=matrix[row2-1][i];
matrix[row2-1][i]=X;
}

Related

How to get norm of a row in Eigen?

I want to get the norm of a row. I've written following code but it's not true!
for (int i = 0; i < A.rows(); i++)
A.row(i) = A.row(i).array() / (A.row(i).norm());
It is worth mentioning, type of A is MatrixXcf. In your opinion, what's the problem?
I don't see any problem with your code. Anyways, what you wrote can be written more compact as either of these:
// assign result to new variable:
Eigen::MatrixXcf N = A.rowwise().normalized();
// or in-place normalization:
A.rowwise().normalize();

How to use memset or fill_n to initialize a dynamic two dimensional array in C++

I have a 2D array created dynamically.
int **abc = new int*[rows];
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
}
I want to fill the array with some value (say 1). I can loop over each item and do it.
But is there a simpler way. I am trying to use memset and std::fill_n as mentioned in this post.
std::fill_n(abc, rows * cols, 1);
memset(abc, 1, rows * cols * sizeof(int));
Using memset crashes my program. Using fill_n gives a compile error.
invalid conversion from 'int' to 'int*' [-fpermissive]
What am I doing wrong here ?
You could just use vector:
std::vector<std::vector<int>> abc(rows, std::vector<int>(cols, 1));
You cannot use std::fill_n or memset on abc directly, it simply will not work. You can only use either on the sub-arrays:
int **abc = new int*[rows];
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
std::fill_n(abc[i], cols, 1);
}
Or make the whole thing single-dimensional:
int *abc = new int[rows * cols];
std::fill_n(abc, rows*cols, 1);
Or I guess you could use std::generate_n in combination with std::fill_n, but this just seems confusing:
int **abc = new int*[rows];
std::generate_n(abc, rows, [cols]{
int* row = new int[cols];
std::fill_n(row, cols, 1);
return row;
});
I think that your main problem here is that you don't have an array of int values. You have an array of pointers to ints.
You probably should start with int* abc = new int[rows * cols]; and work from there, if I understand what you are trying to achieve here.
Just use with * inside the loop you already have:
for (uint32_t i = 0; i < rows; i++)
{
abc[i] = new int[cols];
std::fill_n(*(abc+i), cols, sizeof(int));
}
fill_n don't know where the memory maps the new int array, so you must be carefully coding that way.
I recommend to read:
A proper way to create a matrix in c++
Since you've already got good, workable answers to solve your problem, I want to add just two pointers left and right from the standard path ;-)
a) is just a link to the documentation of Boost.MultiArray
and b) is something I don't recommend you use, but it might help you to understand what you've initially tried. And since your profile shows visual studio tags, you might come in contact with something like this in the win32 api. If that is the case the documentation usually tells you not to use free()/LocalFree()/... on the elements and the "outer" pointer-pointer but to use a specialized function.
(note: I'm not trying to make this code look pretty or clever; it's a mishmash of c and a little c++-ish junk ;-))
const std::size_t rows = 3, cols =4;
int main()
{
std::size_t x,y;
// allocate memory for 0...rows-1 int* pointers _and_ cols*rows ints
int **abc = (int**)malloc( (rows*sizeof(int*)) + cols*rows*sizeof(int) );
// the memory behind abc is large enough to hold the pointers for abc[0...rows-1]
// + the actual data when accessing abc[0...rows-1][0....cols-1]
int* data = (int*)((abc+rows));
// data now points to the memory right after the int*-pointer array
// i.e. &(abc[0][0]) and data should point to the same location when we're done:
// make abc[0] point to the first row (<-> data+(cols*0)), abc[1] point the second row (<-> data+(cols*1)....
for(y=0;y<rows; y++) {
abc[y] = &(data[y*cols]);
}
// now you can use abc almost like a stack 2d array
for(y=0; y<rows; y++) {
for (x=0; x<cols; x++) {
abc[y][x] = 127;
}
}
// and -since the memory block is continuos- you can also (with care) use memset
memset(&abc[0][0], 1, sizeof(int)*rows*cols);
// and with equal care ....
std::fill_n( &(abc[0][0]), rows*cols, 127);
// and get rid of the whole thing with just one call to free
free(abc);
return 0;
}

Inserting values to a multidimensional-vector in C++

I've got a minor problem.
I'm using multidimensional-vectors and I want to insert some values to it at a given position. I'm making a sudoku in wxWidgets and i'm getting the tiles the player have put in and wanting to store them in my mVector.
The mVector looks like this.
vector< vector<string> > board{9, vector<string>(9)};
And at first i've added values just like this.
board[row][col] = value;
"value" is a string and row/col are ints.
Is this a legit way of adding values to the mVector? I'm asking this because when I update the board, by doing this above, I for some reason can't run my other functions where i'm solving the board, giving a hint to the board and so on. Before i store the new values to it all the functions works correkt. Do I maby need to use some other type of build in functions for the vector like insert, push_back or something instead?
Since you declared the vector as size 9x9, yes that is a valid way of assigning values.
Otherwise you could declare the board as
vector<vector<string>> board;
Then fill it with
for (int i = 0; i < 9; ++i)
{
vector<string> row;
for (int j = 0; j < 9; ++j)
{
row.push_back(value); // where value is whatever you want
}
board.push_back(row);
}
But again, once the board is of size 9x9, you can simply assign a value at any cell for example
board[2][4] = "hello";
Working example

how to assign two 2d array

I have written a program which make a 2d array and then set its numbers.
The second step that I have problem in it is that when I want to shift rows and columns I face with a problem in this line nmatrix[i*c+j] = 0;
the error is this : error: incompatible types in assignment of 'int' to 'int [(((sizetype)(((ssizetype)(c + shiftc)) + -1)) + 1)]'
here is the code :
void shiftMatrix(int *matrix, int r,int c ,int shiftr,int shiftc){
int nmatrix [r+shiftr][c+shiftc];
for(int i = 0; i< shiftr; i++)
{
for(int j = 0; j<shiftc;j++)
{
nmatrix[i*c+j] = 0;
}
}
for(int i = shiftr; i< r; i++)
{
for(int j = shiftc; j<c;j++)
{
nmatrix[i*c+j] = matrix[i*c+j];
}
}
}
Any help please??
thanks in advance
int nmatrix [r+shiftr][c+shiftc];
First of all, you are using an array with non-constant bounds, which is a controversial feature.
In addition, here you are declaring a two-dimensional array nmatrix, but your other matrix (matrix) is a pointer to int (or a one-dimensional array, if you like to look at it this way). This is a recipe for confusion.
You can easily declare nmatrix ("new matrix"?) as a one-dimensional array:
int nmatrix[(r+shiftr) * (c+shiftc)];
Or (presumably better)
std::vector<int> nmatrix((r+shiftr) * (c+shiftc));
Then, your code nmatrix[i*c+j] = 0 will work (however, you have to change c to c+shiftc whenever you work with nmatrix).
You cannot define an array dynamically the way you do it.
You need to use the c++ keyword new:
int nmatrix[][] = new int [r+shiftr][c+shiftc];
You cannot define arrays the way you did, with non constant int value for dimension, because such static arrays are to be defined for memory at the compile stage. Thus dimensions should be const expression.
On the contrary with keyword new you can define dimensions for arrays at run-time stage, because it's dynamic allocation.
There are more detailed answers in this SO question here.

2D object array in c++?

2D arrays such as:Cell **scoreTable.After allocating:
scoreTable = new Ceil*[10];
for(int i = 0 ;i<10;i++)
scoreTable[i] = new Ceil[9];
And I want to save the value like this:scoreTable[i][j]= new Ceil(i,j) in heap,and this can not work in c++.Thanks for help.
scoreTable[i][j]= new Ceil(i,j). You are trying to put Cell* into Cell.
You have to create 2d array of pointers:
auto scoreTable = new Ceil**[10];
for(int i = 0 ;i<10;i++)
scoreTable[i] = new Ceil*[9];
But much better is to use vector:
std::vector< std::vector<Ceil*> > table;
table.resize(10);
for (int i = 0; i < 10; ++i)
{
table[i].resize(9, NULL);
}
table[3][4] = new Ceil();
Once you've allocated your array like this, you'll already have a 2D array of Cell, so you don't need to use the new keyword to change the value.
If you give your Cell class a method like SetValue(i,j), then you can use it like this: scoreTable[i][j].SetValue(i,j);
I want to suggest using std::vector instead. It is much easier to keep track of.
You can replace all of the code above with
std::vector< std::vector< Cell> > scoreTable(10, std::vector<Cell>(9));
This will create scoreTable, which is a vector containing 10 elements of vector<Cell>, each containing 9 cells. In other word, the desired 2D table.
You access the elements in the same way. scoreTable[i][j], where i goes fron 0 to 9, and j from 0 to 8.
If you want to expand with a new row, just say:
scoreTable.push_bach(std::vector<Cell>(9));
For a new column:
for(size_t row = 0; row < scoreTable.size(); ++row) {
scoreTable[row].push_back(Cell());
}
No need for new or delete.