I am trying to swap minimum row value with reverse diagonal. I managed to print out every row minimum value, but my swap fails. Maybe you could give me some hints.
for (int i = 0; i < n; i++)
{
int min = mas[i][0];
for (int j = 1; j < m; j++)
{
if (mas[i][j] < min)
{
min = mas[i][j];
}
for(int k=n-1;k>0;k--){
for(int h = m-1; h>0;h--){
min = mas[i][j];
mas[i][j]=mas[k][h];
mas[k][h]=min;
}
cout << "New Matrix\n";
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
cout << mas[i][j] << " ";
}
}
}
}
system("pause");
return EXIT_SUCCESS;
}
This is my for for a minimum value and later I am adding another for to swap values.
My result:
I go printed out 3 matrices and none of them are correctly swapping value. I guess it's because of for in for cycle?
My file with with 2d array:
1 2 5 // row min 1, reverse diagonal 5
2 8 9 // row min 2, reverse diagonal 8
5 9 10 // row min 5, revese diagonal 5
What output I expect:
5 2 1 // 5 diagonal swap with min = 1
8 2 9 // 8 diagonal swap with min = 2
5 9 10 // 5 diagonal no swap because 5 is row minimum
If I understand correctly then the "reverse diagonal" can be present only in a square matrix. So there is no sense to enter two values n and m to deal with a square matrix.
If to consider the example of a 3 x 3 matrix shown in your question and to use loops instead of for example standard functions std::max_element and std::swap then the code that converts the matrix can look the following way as it is shown in the demonstrative program
#include <iostream>
#include <iomanip>
int main()
{
const size_t N = 3;
int a[N][N] =
{
{ 1, 2, 5 },
{ 2, 8, 9 },
{ 5, 9, 10 }
};
for (size_t i = 0; i < N; i++)
{
for (size_t j = 0; j < N; j++)
{
std::cout << std::setw(2) << a[i][j] << ' ';
}
std::cout << '\n';
}
std::cout << std::endl;
for (size_t i = 0; i < N; i++)
{
size_t min = 0;
for (size_t j = 1; j < N; j++)
{
if (a[i][j] < a[i][min]) min = j;
}
if ( min != N - i - 1 )
{
int tmp = a[i][min];
a[i][min] = a[i][N - i - 1];
a[i][N - i - 1] = tmp;
}
}
for (size_t i = 0; i < N; i++)
{
for (size_t j = 0; j < N; j++)
{
std::cout << std::setw(2) << a[i][j] << ' ';
}
std::cout << '\n';
}
std::cout << std::endl;
}
The program output is
1 2 5
2 8 9
5 9 10
5 2 1
8 2 9
5 9 10
Related
I was trying to do the following:
Have a matrix, print the entire thing out, print at end of every row the biggest element of said row and print at the bottom of every column the smallest element of said column.
I'm pretty much a beginner at C++.
So here's what I've done so far:
#include <iostream>
#include <iomanip>
#define M 50
#define N 50
using namespace std;
int main()
{
int m,n;
int a[M][N];
int b[M],c[N];
do {
cout<<"m=";
cin>>m;
cout<<endl<<"n=";
cin>>n;
cout<<endl;
}
while(m!=n);
for(int i=0;i<m; i++) {
for(int j=0; j<n; j++){
cout<<"a["<<i<<"]["<<j<<"]=";
cin>>a[i][j];
}
}
int max_row;
max_row=0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (a[i][j] > max_row) {
max_row = a[i][j];
b[i] = max_row;
}
}
}
for (int i=0; i<m; i++)
{ for(int j=0; j<n; j++){
cout<<setw(3)<<a[i][j]<<"\t";
}
cout<<"|"<<b[i];
cout<<endl;
}
for(int i=0; i<m; i++){
cout<<setw(3)<<"-";}
cout<<endl;
for(int j=0; j<n; j++)
{cout<<c[j]<<"\t";
}
system("pause");
}
Most of the time the max_row are the correct ones such as this case:
3 2 1 |3
4 6 5 |6
7 8 9 |9
Other times they get messed up and it goes like this:
1 2 3 |3
4 33 6 |33
7 8 9 |-858993460
I really have no idea what causes it and since there are no error messages I got really confused. Also I have no idea how to make the min column ones. Any help would be appreciated.
The problem with these loops
max_row=0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (a[i][j] > max_row) {
max_row = a[i][j];
b[i] = max_row;
}
}
}
is that the value of max_row should be initialized with each iteration of the outer loop. Otherwise all rows after the first row deal with the maximum value of the previous row and in general can not have en element that is greater than the current value of max_row. So the corresponding element of the array b will not be initialized.
Also the user can enter for the matrix negative values in this case your program will output zeroes instead of maximum values.
To find maximum elements in rows and minimum elements in columns it is enough to have one pair of nested loops/
Here is a demonstrative program/
#include <iostream>
#include <iomanip>
int main()
{
const size_t N = 3;
int a[N][N] =
{
{ 1, 2, 3 },
{ 4, 33, 6 },
{ 7, 8, 9 }
};
int b[N], c[N];
for ( size_t i = 0; i < N; i++ )
{
b[i] = a[i][0];
c[i] = a[0][i];
for ( size_t j = 1; j < N; j++ )
{
if ( b[i] < a[i][j] ) b[i] = a[i][j];
if ( a[j][i] < c[i] ) c[i] = a[j][i];
}
}
for ( size_t i = 0; i < N; i++ )
{
for ( size_t j = 0; j < N; j++ )
{
std::cout << std::setw( 3 ) << a[i][j] << '\t';
}
std::cout << '|' << b[i] << '\n';
}
for ( size_t i = 0; i < N; i++ )
{
std::cout << std::setw( 3 ) << '-' << '\t';
}
std::cout << '\n';
for ( size_t i = 0; i < N; i++ )
{
std::cout << std::setw( 3 ) << c[i] << '\t';
}
std::cout << '\n';
return 0;
}
Its output is
1 2 3 |3
4 33 6 |33
7 8 9 |9
- - -
1 2 3
The algorithm is supposed to find the minimum cost path in NxN matrix given as an input. The starting cell is always left bottom and the destination is right top.
Each cell of the matrix represents a cost to traverse through that cell.
You can only move up and right.
I have managed to find the cost, however, I still struggle to backtrack the path.
I tried to start from top right cell and use the greedy algorithm to find my "way back", but the output was either completely wrong or skipping random columns/rows. I also tried to keep track of decisions I was making by creating an additional matrix, but I always end up stuck in the loop.
So how do I find the path?
Here's the code that works well (counts the cost and that's it):
#include <iostream>
using namespace std;
int main()
{
int tab[101][101], N, cost[101][101], backtrack[101][101];
cout << "N (size of NxN matrix) :" << endl;
cin >> N;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
cin >> tab[i][j];
cost[i][j] = 0;
backtrack[i][j] = 0;
}
}
cost[N-1][0] = tab[N-1][0];
int a = N-1;
for(int i = N-2; i >= 0; i--) // column 0 can be chosen only in 1 way
{
cost[i][0] = cost[i+1][0] + tab[i][0];
backtrack[i][0] = 4; // came from down
}
for(int j = 1; j < N; j++) // row N-1 can be chosen only in 1 way
{
cost[a][j] = cost[a][j-1] + tab[a][j];
backtrack[a][j] = 3; // came from right
}
for(int i = N-2; i >= 0; i--)
{
for(int j = 1; j < N; j++)
{
if(cost[i][j-1] <= cost[i+1][j])
{
cost[i][j] = tab[i][j] + cost[i][j-1];
backtrack[i][j] = 3;
}
else
{
cost[i][j] = tab[i][j]+cost[i+1][j];
backtrack[i][j] = 4;
}
}
}
cout << "Cost: " << cost[0][a] << endl;
return 0;
}
Now, here's the function with flawed additional matrix that's supposed to give me the path, but ends up in an infinite loop:
(matrix backtrack from previous code was given as track here)
void path(int track[101][101], int N)
{
int help[101][101];
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
help[i][j] = 0;
}
int w = 0, k = N-1;
help[w][k] = 1; // top right argument is included in the output
while(w < N || k >= 0)
{
if(track[w][k] == 3)
{
help[w][k-1] = 1; // 3 means I came from the previous column k-1
k--;
}
else if(track[w][k] == 4)
{
help[w+1][k] = 1; //4 means I came from the previous row w+1
w++;
}
}
for(int i = 0; i < N; i++)
{
for(int j = 0; j < N; j++)
{
if(help[i][j] != 0)
cout << i << " " << j << endl;
}
}
}
Example input:
5
2 3 4 2 5
5 2 1 2 2
2 4 2 2 3
1 2 2 4 3
3 2 1 2 3
Expected output:
Cost: 20
4 0
4 1
4 2
3 2
2 2
1 2
1 3
0 3
0 4
Actual output
Cost: 20
And no path at all since it ends up in an infinite loop.
You have written the while loop in path() incorrectly:
while(w < N || k >= 0)
...
You intend this loop to continue until w = N-1 and k=0, which it does, but the loop doesn't terminate there, it just runs in place. (You could see this yourself by adding cout << w << " " << k << endl; to the loop.) The conditional I think you want is:
while(w < N-1 || k > 0)
I'm having trouble with a matrix . The requirements are:
Make a matrix with N columns and N rows, the first column must have the value N , the second column must have N-1, the third N-2 etc until the last column must have value 1.
For example: N[7][7] must be:
7 6 5 4 3 2 1
7 6 5 4 3 2 1
7 6 5 4 3 2 1
7 6 5 4 3 2 1
7 6 5 4 3 2 1
7 6 5 4 3 2 1
7 6 5 4 3 2 1
My code only gets : 7 6 6 6 6 6 6 for each row and column. How can I solve this?
#include <iostream>
using namespace std;
int main()
{
int m[24][24], i, j, k = 0;
int linia, coloana, piesa, lac=0;
int mutari = 0;
int ceva;
cout << "Cate linii si cate coloane ? :";
cin >> lac;
ceva = lac;
if (lac>1 && lac<25) {
for (i = 0; i < lac; i++)
{
for (j = 0; j < lac; j++)
{
m[i][0] = lac;
m[i][1] = ceva-1;
ceva = ceva;
m[i][j] = ceva - 1;
ceva = ceva;
if (i == j) {
m[i][j] = 2;
m[1][1] = 2;
}
};
};
for (i = 0; i < lac; i++)
{
for (j = 0; j < lac; j++)
{
cout << m[i][j] << " ";
}
cout << endl;
}
}
else cout << "Numarul de linii si coloane trebuie sa fie >=2 si <= 24" << endl;
return 0;
}
The following code should neatly initalize the matrix.
if (lac>1 && lac<25) {
for (i = 0; i < lac; i++)
{
ceva = lac;
for (j = 0; j < lac; j++)
{
m[i][j] = ceva;
ceva = ceva-1;
}
} // no need for ';' here
for (i = 0; i < lac; i++)
{
for (j = 0; j < lac; j++)
{
cout << m[i][j] << " ";
}
cout << endl;
}
}
At the beginning of each row, we use ceva = lac; to reset the value that will go into the matrix.
Immediately after setting the value, we decrease ceva by one.
I stripped out a lot of code whose purpose I did not understand.
After Tim Randall showed you how to fix your code, this is the C++ way of doing things:
#include <cstddef>
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
std::cout << "Rows: ";
std::size_t rows;
std::cin >> rows;
std::cout << "Columns: ";
std::size_t cols;
std::cin >> cols;
std::size_t elements{ rows * cols };
std::vector<int> m(elements);
std::generate(m.begin(), m.end(), [&]() { return --elements % cols + 1; });
for (std::size_t y{}; y < rows; ++y, std::cout.put('\n'))
std::copy(m.begin() + y * cols, m.begin() + (y + 1) * cols,
std::ostream_iterator<int>(std::cout, " "));
// access m[y][x] with m[y * cols + x]
}
Make it easier on yourself and leverage the power of the standard library.
constexpr auto N = 7;
std::array<int, N> row{};
std::array<std::array<int, N>, N> matrix{};
std::iota(std::rbegin(row), std::rend(row), 1);
std::fill(std::begin(matrix), std::end(matrix), row);
std::array is just a very thin wrapper around c-style arrays, is slightly nicer to work with, and has nice features such as remembering its size.
std::iota fills a range with sequentially increasing values (in this case starting at 1). By using std::rbegin, we tell it to fill our row in reverse.
Finally we use std::fill to set each row of our matrix to row.
The code will work even on c++11, by replacing std::rbegin with .rbegin().
I have a loop in each iterate an array is printed. now I need this array so I want to put them in a 2 dimension vector. I wrote this code but I dont know why it does not work!
when I run it does not print any thing and it dont show any error!
int main() {
int i, u;
const int j = 9;
vector<vector<int>> V;
int B[9] = {};
for (int r = 0; r<10; r++) {
B[r] = 1;
for (int t = 0; t<V.size(); t++) {
for (int w = 0; w<j; w++, u++) {
V[t][w] = B[u];
}
}
}
for (int m = 0; m<V.size(); m++) {
for (int k = 0; k<j; k++) {
cout << "V=" << " " << V[m][k];
}
}
return 0;
}
For example in the first loop in each iterate B changes and I want to store all of them in a matrix! for example I have:
first iterate: B=(1,0,0)
second iterate: B=(0,1,0)
third iterate: B=(0,0,1)
now I want to have:
V={{1,0,0},{0,1,0},{0,0,1}}
Let's say that you have N int[N] values, and you want 1 vector<vector<int>> value.
std::vector<int> fromArray(int (&B)[N])
{
return { std::begin(B), std::end(B) };
}
This is a function that will turn a 1D array into a 1D vector. you will need to call it N times.
std::vector<std::vector<int>> fromArrays(int (&Bs)[N][N])
{
std::vector<std::vector<int>> result{ N };
std::transform(std::begin(Bs), std::end(Bs), result.begin(), fromArray);
return result;
}
Here we take a 2D array and turn it into a 2D vector. This requires you have all the Bs together.
int main()
{
constexpr int N = 3;
std::vector<std::vector<int>> V;
for (int i = 0; i < N; ++i)
{
int B[N] = {};
B[i] = 1;
V.emplace_back(fromArray(B));
}
for (std::vector<int> & v : V)
{
for (int i : v)
{
std::cout << i << " ";
}
std::cout << "\n";
}
return 0;
}
Alternately, if you don't have all the Bs all in one go, just loop N times getting one B
If guessing, there is a my implementation:
int main() {
int len = 9;
int div = 3;
int total = len / div;
int B[len]={1, 0, 0, 0, 1, 0, 0, 0, 1};
vector<vector<int> > V(total);
int cnt = 0;
for (int i = 0; i < len && cnt < total; i += div) {
for (int j = i; j < i + div; j++) {
V[cnt].push_back(B[j]);
}cnt++;
}
for (int i = 0; i < total; i++) {
for (int j = 0; j < V[i].size(); j++) {
cout << V[i][j] << " ";
}cout << endl;
}
return 0;
}
V is like this:
1 0 0
0 1 0
0 0 1
You probably want this:
int main() {
const int Bsize = 9;
const int NumberOfLines = 4; // number of iterations
int B[Bsize] = { 1,2,3,4,5,6,7,8,9 };
vector<vector<int>> V;
V.resize(NumberOfLines);
int bIndex = 0;
for (int r = 0; r < NumberOfLines; r++) {
// add code that changes B here
V[r].resize(Bsize);
for (int w = 0; w < Bsize; w++) {
V[r][w] = B[w];
}
}
for (int m = 0; m < V.size(); m++) {
for (int k = 0; k < V[m].size(); k++) {
cout << " " << V[m][k];
}
cout << endl;
}
return 0;
}
In this sample we'll generate 4 lines (one for each iteration), but B is each time the same here. If you want B to change between each iteration, you need to insert the corresponding code that changes B.
The output of the sample will be:
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
I am trying to find min (by row) and max (by column) element in two-dimensional (4,4) array and then store them in new array (5,5).
That is how it should look for new array (5,5):
1 2 3 4 min
5 6 7 8 min
4 4 4 5 min
3 5 5 6 min
m m m m 0
*m - max
Here it is the entire code:
#include <iostream>
using namespace std;
int main() {
int A[4][4];/*First array*/
int i, j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++) {
cout << "\n A[" << i + 1 << "][" << j + 1 << "]=";
cin >> A[i][j];
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++)
cout << A[i][j] << "\t";
cout << "\n";
}
{
int min[4];/* find min on each row*/
for (i = 0; i < 4; i++) {
min[i] = A[0][i];
for (j = 1; j < 4; j++) {
if (min[i] > A[i][j])
min[i] = A[i][j];
}
}
int newarr[5][5];/* here i create the new array 5,5)*/
int max[5] = { 1,2,3,4,5 };
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
newarr[i][j] = A[i][j];
newarr[i][5] = max[i];
}
}
for (j = 0; j < 4; j++)
newarr[5][j] = min[j];
cout << newarr[5][j] << "\t";
cout << "\n";
}
}
I put random elements to max. Because so far I only test. But once I started my program it show correct only the first array. And where should be the new array it shows zero. Here it is the outcome of the debugging:
5 4 3 1
5 6 7 9
4 2 3 9
4 8 4 6
0
How to fix it?
And how to put zero in the last element (as you can see in the first table for the new array).
You can do it in a single pass over all the elements:
// returns a (rows+1, cols+1) matrix
int* make_min_max_vectors(const int* arr, size_t rows, size_t cols) {
size_t out_size = (rows+1) * (cols+1);
int* res = malloc(out_size * sizeof(int));
// set up initial values in the right/bottom vectors
res[out_size - 1] = 0;
for (size_t col = 0; col < cols; ++col)
res[rows*(cols+1) + col] = INT_MIN;
for (size_t row = 0; row < rows; ++row)
res[row*(cols+1) + cols] = INT_MAX;
for (size_t row = 0; row < rows; ++row)
for (size_t col = 0; col < cols; ++col) {
const int* cell = &arr[row*cols + col];
res[row*(cols+1) + col] = *cell; // copy
if (*cell < res[row*(cols+1) + cols]) // min
res[row*(cols+1) + cols] = *cell;
if (*cell < res[rows*(cols+1) + col]) // max
res[rows*(cols+1) + col] = *cell;
}
}
return res;
}
That is, you simply run over all the input elements once, copying each one to the output plus checking if each one is less than its row minimum or greater than its column maximum. You don't need temporary vectors for min and max, and you don't need to run over the entire input twice.
John Swincks answer is awesome (+1'd) and I would definitely recommend his answer simply for future proofing your code. I am relatively new to programming myself and understand how intimidating the above code can seem (especially malloc). Because of this I have written the a version of your code that is very similar however gets rid of the need to have the original 4x4 matrix and instead uses a 5x5. The code is shown below, let me know if you have any issue with it. The code can be compiled as is and will demonstrate what you are trying to acheive.
#include <iostream>
int main()
{
// Initialised inline to simplify example.
int A[5][5] = {0};
// Only uses 4x4 of the 5x5 array meaning that you don't need to use two arrays.
for (int x = 0; x < 4; ++x)
{
for (int y = 0; y < 4; ++y)
{
std::cout << "Enter in value for row " << x << ", column " << y << ".\n";
std::cin >> A[x][y];
}
}
std::cout << "Input:" << std::endl;
for (int x = 0; x < 4; ++x)
{
for (int y = 0; y < 4; ++y)
{
std::cout << A[x][y] << "\t";
}
std::cout << "\n";
}
// Finds the max down each column in the array
for (int x = 0; x < 4; ++x)
{
for (int y = 0; y < 4; ++y)
{
if (A[x][4] < A[x][y])
A[x][4] = A[x][y];
}
}
// Finds the min across the array (along row)
for (int y = 0; y < 4; ++y)
{
for (int x = 0; x < 4; ++x)
{
// Assign the min to a value in that row.
A[4][y] = A[1][y];
if (A[4][y] > A[x][y])
A[4][y] = A[x][y];
}
}
std::cout << "Output:" << std::endl;
for (int x = 0; x < 5; ++x)
{
for (int y = 0; y < 5; ++y)
{
std::cout << A[x][y] << "\t";
}
std::cout << "\n";
}
std::cin.get();
std::cin.get();
return 0;
}
Edit: Sample input and output for clarification.
Input:
1 2 3 4
5 62 4 6
8 9 1 2
4 6 8 9
Output:
1 2 3 4 1
5 62 4 6 4
8 9 1 2 1
4 6 8 9 4
8 62 8 9 0