Problem in rearranging rows and columns of an array - c++

In general, given the task:
A permissible matrix transformation is a permutation of two adjacent rows or two neighboring columns. A real square matrix of order n (n <= 12) is given. Using valid converters, you can get a matrix in which the maximum element is in the upper left corner. Elements were used to perform valid conversions.
My problem is precisely that I cannot swap adjacent rows or columns.
Here is my code:
#include <iostream>
#include <algorithm>
using namespace std;
const int rows = 4, cols = rows;
int iMax = 0;
int jMax = 0;
int arr[rows][cols];
void arr_f()
{
setlocale(LC_ALL, "rus");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cin >> arr[i][j];
}
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << " " << arr[i][j] << "\t";
if (arr[i][j] > arr[iMax][jMax])
{
iMax = i;
jMax = j;
}
}
cout << endl;
}
cout << endl << "The maximum number of array: " << arr[iMax][jMax] << endl << endl;
}
int main()
{
arr_f();
system("pause");
}
Tried to add features
inline void swap_columns(const int f, const int s)
{
for (int i = 0; i < rows; ++i)
{
swap(arr[i][f], arr[i][s]);
}
}
inline void swap_rows(const int f, const int s)
{
for (int i = 0; i < rows; ++i)
{
swap(arr[f][i], arr[s][i]);
}
}
and add the following to the arr_f () function:
swap_rows(0, iMax);
swap_columns(0, jMax);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << " " << arr[i][j] << "\t";
}
cout << endl;
}
But in this case, the rows (and columns) do not change as expected (the row in which the maximum value is located is immediately replaced by the first row, ignoring the rest).

You obtained a wrong result, because swap_columns and swap_rows make operations that are not allowed. You need to make them this way:
inline void swap_columns(const int k)
{
for (int i = 0; i < rows; ++i)
{
swap(arr[i][k], arr[i][k+1]);
}
}
inline void swap_rows(const int k)
{
for (int i = 0; i < rows; ++i)
{
swap(arr[k][i], arr[k+1][i]);
}
}
And apply this way:
for (int k = iMax-1; k >= 0; --k)
swap_rows(k);
for (int k = jMax-1; k >= 0; --k)
swap_columns(k);
Certainly, this may be improved by moving larger blocks, but this is a matter of optimization.

To swap adjacent rows and columns, just replace this:
swap_rows(0, iMax);
swap_columns(0, jMax);
with this:
swap_rows(iMax + 1, iMax);
swap_columns(jMax + 1, jMax);
However, it is not clear from the problem description, whether this would always be the desired solution. And if iMax happens to be the last row index, then iMax + 1 would be out of bounds and fail at run time. In that case, perhaps iMax - 1 would be required instead.

Related

Armadillo altering entire columns instead of singular elements when attempting to copy from another matrix class

I am trying to copy a matrix from an old matrix class to an armadillo matrix. Unfortunately when attempting to do this with a for loop the armadillo matrix will copy the value from the old matrix to the ENTIRE column when the lowest-most element is non-zero (I am using sparse matrices). I have attached the code that is being used below. This is very simplified because I need to figure out why it is doing this first. According to the documentation this should work.
main()
{
OldMatrixClass MatrixA(size, size);
FillMatrix(MatrixA, size);
for (auto i = 0; i < size; i++)
{
for (auto j = 0; j < size; j++)
{
file << MatrixA[i][j] << "\t";
}
file << "\n";
}
arma::Mat<double> ArmaA(size, size);
ArmaA.zeros();
CopyMatrix(MatrixA, ArmaA, size);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
file << ArmaA[i,j] << "\t";
}
file << "\n";
}
}
void FillMatrix(OldMatrixClass &A, int size)
{
double num = 0.15;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (rand() % 101 < 26)
{
A[i][j] = num;
}
else
{
A[i][j] = 0;
}
}
}
}
void CopyMatrix(OldMatrixClass A, arma::Mat<double> &B, int size)
{
for (int k = 0; k < size; k++)
{
for (int j = 0; j < size; j++)
{
B[j, k] = A[j][k];
}
}
}
This is the output when I run this code... As you can see only the entire columns are altered if the last element in MatrixA column is non-zero.
Output
Is there something I'm doing wrong? Is my syntax messed up somewhere?
See the documentation:
Caveat: accessing elements via [i,j] and [i,j,k] does not work correctly in C++; instead use (i,j) and (i,j,k)

Showing garbage values when adding two matrix using operator overloading

Please help me as I am new to programming and I have made this program and it looks fine to me but I am getting garbage values instead of sum of two matrix.I have applied the concept of operator overloading to find the sum of two matrices but I am getting garbage values again and again?Please help me that where is the problem?Thanks.Any help is completely appreciated
#include<iostream>
#include<string>
using namespace std;
class Matrix {
private:
int matrix[2][2];
public:
Matrix operator + (Matrix Sum)
{
Matrix sum[2][2];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
sum[i][j].matrix[i][j] = matrix[i][j] + Sum.matrix[i][j];
return(sum[i][j]);
}
}
}
void setMatrix(int m[][2])
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
matrix[i][j] = m[i][j];
}
}
}
void Display()
{
cout << "\n\nThe matrix finally equals: ";
for (int i = 0; i < 2; i++)
{
cout << " ";
for (int j = 0; j < 2; j++)
{
cout<<matrix[i][j];
if (j == 2 - 1)
cout << endl;
}
}
}
};
int main()
{
Matrix m1, m2,sum;
const int size=2;
int matrix1[size][size];
int matrix2[size][size];
cout << "Enter the values of matrix 1 (2 X 2)\n\n";
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
cin >> matrix1[i][j];
}
}
cout << "Enter the values of matrix 2 (2 X 2)\n\n";
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
cin >> matrix2[i][j];
}
}
cout <<"\n\nSetting the values now\n\n";
m1.setMatrix(matrix1);
m2.setMatrix(matrix2);
sum = m1 + m2;
cout << "\n\nMatrix 1 (2 X 2) is : ";
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
cout << matrix1[i][j] << " ";
if (j == size - 1)
cout << endl;
}
}
cout << "\n\nMatrix 2 (2 X 2) is : ";
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
cout << matrix2[i][j] << " ";
if (j == size - 1)
cout << endl;
}
}
cout << "\n\nSum of two matrices is equal to (2 X 2) is : ";
sum.Display();
return 0;
}
Let's take a close look at you operator+, there are two major errors:
Matrix sum[2][2]; is an array of matrices, but you want to return only a single Matrix, not multiple. Also the name is bad, because you already have a parameter with a similiar name. And yes, C++ is case sensitive, but such similiar names are problematic for human readers ;).
Look where the return is. It will return during the first iteration, e.g.
sum[i][j].matrix[i][j] = matrix[i][j] + Sum.matrix[i][j];
will be called just once, with i and j being zero. Thus it sets only one entry and returns immediately afterwards (leaving the other 3 values uninitialized). That's where the garbage values come from, technically it's undefined behaviour.
Here is what the function should look like, but please don't just copy-paste, but take some time to understand it.
Matrix operator + (Matrix rhs) // One of the two names needed to change.
{
Matrix sum; //only one value with a proper name
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
// better be explicit and use this, imo
sum.matrix[i][j] = this->matrix[i][j] + rhs.matrix[i][j];
}
}
return sum; // return only after all the calculations.
}

How do I set all the diagonals in a matrix equal to zero?

I have a problem with my homework that asks me to have the compiler print out a matrix in which all the diagonals are outputted as zero. I also have to pass it to a function. However, I have no idea how to do this..
Here is my code:
#include <iostream>
using namespace std;
int diagonals();
int main()
{
//problem 1
int matrix[3][3];
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3 ; j++)
{
cout << "Row " << i << " column " << j<< ": ";
cin >> matrix[i][j];
}
}
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << "\nReverse of the matrix:" << endl;
for (int j = 1; j <= 3; j++)
{
for (int i = 1; i <= 3; i++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}//end of problem 1
//problem 2
cout << "Diagonals changed to 0:\n" << endl;
}
your matrix declaration says int matrix[3][3]; that it has three 1-D array & in each 1-D array you can store three elements. And in C/C++ array index starts from zero.
Problematic statement is for (int i = 1; i <= 3; i++) as you are skipping matrix[0][0] and trying to store into matrix[3][3] which doesn't exist which in turn causes undefined behavior.
So firstly start iterating loop from 0 to number of rows & column respectively.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3 ; j++) {
cout << "Row " << i << " column " << j<< ": ";
cin >> matrix[i][j];
}
}
Coming to task you mentioned, print out a matrix in which all the diagonals are outputted as zero. ? write one condition so that if row value & col value are equal then assign it to zero otherwise scan from user. Here is the sample code
int main(void) {
int matrix[3][3] = { 0 }; /* initialize it */
int row = sizeof(matrix)/sizeof(matrix[0]); /* find no of rows */
int col = sizeof(matrix[0])/sizeof(matrix[0][0]);/* find no of columns */
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if( i == j)
matrix[i][j] = 0;/* when i and j are equal means thats diagonal and assign it to zero */
else /* if its not diagonal then scan from user */
std::cin>>matrix[i][j];
}
}
return 0;
}
Secondly, I also have to pass it to a function. for this learn how to pass 2d array to a function. Here is the sample example.
void diagonal(int (*mat)[3],int row, int col) { /* mat is pointer to an array */
std::cout<<"printing matrix "<<std::endl;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
std::cout<<mat[i][j]<<"\t";
}
std::cout<<std::endl;
}
}
And call diagonal() like below from main() function as
diagonal(matrix,row,col); /* pass matrix, no of rows, no of columns */

Finding the maximum value of every row in 2D array C++

I've managed to find the minimum value of every row of my 2D array with this
void findLowest(int A[][Cm], int n, int m)
{
int min = A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] < min)
{
min = A[i][j];
}
}
out << i << " row's lowest value " << min << endl;
}
}
I'am trying to find the maximum value of every row using the same way,but it only shows me first maximum value
void findHighest(int A[][Cm], int n, int m)
{
int max = A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] > max)
{
max = A[i][j];
}
}
out << i << " row's highest value " << max << endl;
}
}
I can't find what's wrong with the second function and why is it only showing me the first maximum value it finds. Any help ?
Both functions return the result (maximum or minimum) for the whole array rather than each row, because you set max once rather than once per row. You can get the result for each row as follows:
void findHighest(int A[][Cm], int n, int m)
{
for (int i = 0; i < n; i++)
{
int max = A[i][0];
for (int j = 1; j < m; j++)
{
if (A[i][j] > max)
{
max = A[i][j];
}
}
// do something with max
}
}
or, even better, use the standard library function max_element:
void findHighest(int A[][Cm], int n, int m)
{
if (m <= 0) return;
for (int i = 0; i < n; i++)
{
int max = *std::max_element(A[i], A[i] + m);
// do something with max
}
}
This should give you all values which is easy to check:
#include <algorithm>
#include <iostream>
enum { Cm = 2 };
void findHighest(int A[][Cm], int n, int m) {
if (m <= 0) return;
for (int i = 0; i < n; i++) {
int max = *std::max_element(A[i], A[i] + m);
std::cout << max << " ";
}
}
int main() {
int A[2][2] = {{1, 2}, {3, 4}};
findHighest(A, 2, 2);
}
prints 2 4.
If your compiler supports C++11, for concrete arrays you could use the following alternative, that's based on std::minmax_element:
template<typename T, std::size_t N, std::size_t M>
void
minmax_row(T const (&arr)[N][M], T (&mincol)[N], T (&maxcol)[N]) {
for(int i(0); i < N; ++i) {
auto mnmx = std::minmax_element(std::begin(arr[i]), std::end(arr[i]));
if(mnmx.first != std::end(arr[i])) mincol[i] = *(mnmx.first);
if(mnmx.second != std::end(arr[i])) maxcol[i] = *(mnmx.second);
}
}
Live Demo
Your test data is guilty for not clearly showing you the defect.
The row minima occur in decreasing values, so that they get updated on every row.
And the row maxima also occur in decreasing values, so that the first one keeps winning.
As others pointed, your function finds the global minimum/maximum, no the per-row extrema.
Move the initialization of the min/max variable inside the outer loop.
As mentioned your code only shows the maximum element in the whole array.
Here is the code which will help you.
void findHighest(int A[][Cm], int n, int m)
{
int max[n];
max[0]=A[0][0];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (A[i][j] > max[i])
{
max[i] = A[i][j];
}
}
cout << i << " row's highest value " << max[i] << endl;
}
}
{
int i,j;
int arr[4][2]={(1,2),(3,4),(5,6),(7,8)};
int max;
max=arr[0][0];
for( int i=0; i<4; i++)
{
for(int j=0; j<2; j++)
{
if(max<arr[i][j])
{
max=arr[i][j];
}
}
}
int min;
min=arr[0][0];
for(int i=0; i<4; i++)
{
for(int j=0; j<2; j++)
{
if(min>arr[i][j])
{
min=arr[i][j];
}
}
}
cout<<"maximum number is:"<<max;
cout<<endl;
cout<<"Minimum Number is:"<<min;
}

Replacing values in a 2D array

I have to create a program that allows a user to fill in a (partial) Latin Square of order 4. You can use 0's to represent empty cells. The user will give the number to place, the row and column. The number should only be placed if it does not violate the properties of a partial Latin square and it shouldn't rewrite numbers that have already been placed.
I have an matrix that is outputting all zeroes now. So next I have to replace each of these values by what the user is inputting. The problem is I don't know how to do this.
Here is my code:
#include <iostream>
using namespace std;
const int ORDER = 4;
void fill (int m[], int order);
void outputMatrix (int m[], int order);
void replaceValue (int m[], int order, int n, int row, int column);
int main(){
int matrix[ORDER];
int row;
int column;
int n;
fill (matrix, ORDER);
outputMatrix (matrix, ORDER);
do {
cout << "Enter the number to place, the row and the column, each seperated by a space: ";
cin >> n;
cin >> row;
cin >> column;
}while (n > 0 || n <= ORDER);
if (n <= 0 || n >= ORDER){
cout << "Thank you";
cout << endl;
}
return 0;
}
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
void outputMatrix (int m[], int order){
int c = 0;
for (int i = 0; i < order*order; i++){
c++;
cout << m[i] << ' ';
if (c == order){
cout << endl;
c = 0;
}
}
cout << endl;
}
void replaceValue (int m[], int order, int n, int row, int column){
for (int i = 0; i < order; i++){
m[order] = m[row][column];
m[row][column] = n;
}
}
How do I replace values in a Matrix in C++?
If you have a matrix, matrix[row][col] = value; would do the trick. However, I see that you allocate a single array. Make sure you look at this.
EDIT:
I looked closer at you code and you are doing some things wrong.
First:
matrix[ORDER]
will create a single array of ORDER values. If you want and ORDER by ORDER matrix try:
matrix[ORDER][ORDER]
Second:
You are calling:
void fill (int m[], int order){
for (int i = 0; i < order*order; i++){
m[i] = 0;
}
}
with an of size 4 and order == 4. This will loop outside the array and give you problems.
Try something like:
matrix[ORDER][ORDER];
for (int row = 0; row != ORDER; ++row)
{
for (int col = 0; col != ORDER; ++col)
{
matrix[row][col] = 0;
}
}
Hope this helps.
You can't really write arr[i][j] if arr is defined as arr[]. There's no information about the length of the row (how many columns there are).
You could use arrays of type arr[][4], and write your functions like so:
// The & is to pass by reference.
void print(int (&arr)[][4], int length)
{
for(int i = 0; i < length; i++) {
for(int j = 0; j < 4; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
But in my opinion for a low-order multidimensional array like this one, using a typedef for a vector of vectors is the better option:
typedef vector<vector<int> > Matrix;
void print(Matrix& arr)
{
for(int i = 0; i < arr.size(); i++) {
for(int j = 0; j < arr[i].size(); j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
In either case, writing arr[i][j] = k will behave as you expect.
The easiest way to clear/zero your matrix is that:
memset( &matrix, 0, sizeof(matrix));
;-)