This code can only return one smallest element in a matrix, but how if I want to return smallest element in each row? I need to use recursive function in C++. Thanks for your help
#include<iostream>
using namespace std;
int smallest(int** arr, int rows, int columns, int column_index = 0)
{
if (rows <= 0 || column_index >= columns)
return INT_MAX;
if (rows == 1)
return min(*(*arr + column_index),
smallest(arr, 1, columns - 1,
column_index + 1));
return min(smallest(arr, 1, columns),
smallest(arr + 1, rows - 1, columns));
}
int main()
{
int row, col, index=0;
cin >> row;
cin >> col;
int** arr;
arr = new int* [row];
for (int i = 0; i < row; i++) {
arr[i] = new int[col];
for (int j = 0; j < col; j++) {
cin >> arr[i][j];
}
}
cout<<smallest(arr, row, col, index);
return 0;
}
I think this much code will be sufficient if you use standard algorithm - std::min_element:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
int r, c;
std::cin >> r >> c;
std::vector<std::vector<int>> mat(r, std::vector<int>(c));
for (auto &&row : mat)
for (auto &&ele : row)
std::cin >> ele;
for (auto &&row : mat)
std::cout << *std::min_element(row.begin(), row.end()) << std::endl;
}
If you want to do it your way (old school style, using recursion) then do something like this. You just need to fix the index of row while calling smallest. Below is some self-explanatory code :
#include <algorithm>
#include <iostream>
// here row_index represents the index of row and col represents the number of
// elements in that row which are not yet traversed (counted from beginning)
int smallest(int **arr, int row_index, int col) {
// only first element is not traversed
if (col == 1)
return arr[row_index][0];
// return minimum of last element and value returned by recursive call for
// first col - 1 elements
return std::min(arr[row_index][col - 1], smallest(arr, row_index, col - 1));
}
int main() {
int row, col;
std::cin >> row;
std::cin >> col;
int **arr = new int *[row];
for (int i = 0; i < row; i++) {
arr[i] = new int[col];
for (int j = 0; j < col; j++)
std::cin >> arr[i][j];
}
// call the function for each row
for (int i = 0; i < row; i++)
std::cout << "Smallest element in row " << i + 1 << " : "
<< smallest(arr, i, col) << '\n';
}
You can write a recursive function that finds the smallest element in a one-dimensional array that will be called for each "row" of an array of arrays or of a two-dimensional array.
Here is a demonstrative program.
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstdlib>
#include <ctime>
const int * smallest( const int *a, size_t n )
{
return n < 2 ? a
: std::min( a, smallest( a + 1, n - 1 ),
[]( const int *p1, const int *p2 )
{
return not ( *p2 < *p1 );
} );
}
int main()
{
std::srand( ( unsigned int )std::time( nullptr ) );
size_t rows, cols;
std::cin >> rows >> cols;
int **a = new int *[rows];
for ( size_t i = 0; i < rows; i++ )
{
a[i] = new int[cols];
for ( size_t j = 0; j < cols; j++ )
{
a[i][j] = std::rand() % ( rows + cols );
}
}
for ( size_t i = 0; i < rows; i++ )
{
for ( size_t j = 0; j < cols; j++ )
{
std::cout << std::setw( 2 ) << a[i][j] << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
for ( size_t i = 0; i < rows; i++ )
{
std::cout << std::setw( 2 ) << *smallest( a[i], cols ) << ' ';
}
std::cout << '\n';
for ( size_t i = 0; i < rows; i++ )
{
delete [] a[i];
}
delete [] a;
}
If to enter the numbers of rows and columns equal to 10 then the program output might look like
1 16 7 6 2 7 1 14 3 8
0 14 9 0 6 18 18 7 7 19
12 17 9 12 14 10 7 9 15 3
14 8 19 13 14 1 12 15 7 15
16 7 1 17 19 8 15 18 7 15
9 19 12 10 3 18 0 10 7 8
6 13 16 17 7 3 19 19 18 6
7 14 6 8 3 17 8 19 7 16
6 16 7 10 19 11 1 19 13 8
19 19 14 8 17 1 11 8 12 1
1 0 3 1 1 0 3 3 1 1
Pay attention to that the function should return a pointer to a smallest element because in general the function can be called with the second argument equal to 0. In this case returning any integer value does not make a sense because it can coincide with an actual value.
Related
I am attempting to print out an array in a specific order, where it is formatted with columns and rows in ascending order, but with the bottom row containing the lowest values. The array is created via a for loop and a pointer.
here is my code so far:
#include <iostream>
#include <iomanip>
int main()
{
// Creation of the array
int* array = new int[24];
for (int i = 0; i < 24; i++)
{
array[i] = i;
}
// Displaying in grid format with 3 rows and 8 columns
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 8; j++)
{
std::cout << std::setw(2) << *array << ' ';
array++;
}
std::cout << '\n';
}
}
The output of my code is:
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
The desired output is:
16 17 18 19 20 21 22 23
8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7
How would I go about "reversing" the rows to reach the desired output?
SOLVED WITH THE FOLLOWING
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int* table = new int[40];
for (int i = 0; i < 40; ++i)
{
table[i] = i;
}
for (int i = 4; i >= 0; --i)
{
for (int j = 0; j < 8; ++j)
{
cout << setw(2) << table[j + (8 * i)] << ' ';
}
cout << "\n";
}
}
Thanks for the help.
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'm stuck on this. Could you please help me?
Write a function which initialize a two-dimensional array. The array is a square
matrix (i.e., its width and height are identical.) The array should be initialized in the
zig-zag style. Specifically, we start at the top-left corner and go downward, and put a
number starting from 1. Once we hit the bottom, we go to the next column and fill in
the numbers from bottom to top. We fill the numbers downward in the third
column, upward in the fourth column, and so on. The process ends when all the
elements in the array are filled.
However, How do I get my output like this?
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
#include <iomanip>
#include <iostream>
using namespace std;
const int SIZE = 5; // Note SIZE can be anything between 1 to 9
void initGrid(int grid[SIZE][SIZE]);
void printGrid(int grid[SIZE][SIZE]);
int main() {
int grid[SIZE][SIZE];
initGrid(grid);
printGrid(grid);
}
void initGrid(int grid[SIZE][SIZE]) {
int inc = 1;
for (int j = 0; j < SIZE; j++) {
for (int i = 0; i < SIZE; i++) {
grid[i][j] = inc;
inc++;
}
}
}
void printGrid(int grid[SIZE][SIZE]) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
// setw() function handles the printing format.
cout << setw(2) << grid[i][j] << " ";
}
cout << endl;
}
}
Every two columns of the grid share the same filling pattern, the odd ones are filled in ascending order, the even ones in descending order. All you have to do is translate that into code:
template<size_t Rows, size_t Cols>
void initGrid(int (&grid)[Rows][Cols]) {
int value = 1;
for (size_t j = 0; j < Cols; ++j) {
// first fill the odd column in descending order
for (size_t i = 0; i < Rows; ++i, ++value) {
grid[i][j] = value;
}
// then, if there is one, fill the even column
++j;
if (j == Cols )
break;
for (size_t i = Rows; i > 0; ++value) {
--i; // size_t is unsigned, so I have to check i before decrementing
grid[i][j] = value;
}
}
}
I used the same data structure you used (but a different function signature) only to focus on the algorithm, but I'd use a class instead.
If you don't want to traverse the array column-wise (which, for big arrays, could result in performance drop due to cache misses) you can calculate the differences between values in every row:
template<size_t Rows, size_t Cols>
void zig_zag_fill(int (&grid)[Rows][Cols])
{
int diff_up = 1;
int diff_down = Rows * 2 - 1;
for (size_t i = 0; i < Rows; ++i, diff_down -= 2, diff_up += 2)
{
int value = i + 1;
size_t j = 0;
while ( j < Cols )
{
grid[i][j] = value;
value += diff_down;
++j;
if ( j == Cols )
break;
grid[i][j] = value;
value += diff_up;
++j;
}
}
}
A complete test program like this:
#include <iostream>
#include <iomanip>
template<size_t Rows, size_t Cols>
void zig_zag_fill(int (&grid)[Rows][Cols]);
template<size_t Rows, size_t Cols>
void printGrid(int (&grid)[Rows][Cols]);
int main() {
int grid[5][6];
zig_zag_fill(grid);
printGrid(grid);
std::cout << '\n';
int grid2[6][5];
zig_zag_fill(grid2);
printGrid(grid2);
std::cout << '\n';
int grid3[5][5];
zig_zag_fill(grid3);
printGrid(grid3);
std::cout << '\n';
int grid4[6][6];
zig_zag_fill(grid4);
printGrid(grid4);
std::cout << '\n';
}
template<size_t Rows, size_t Cols>
void initGrid(int (&grid)[Rows][Cols]) {
int value = 1;
for (size_t j = 0; j < Cols; ++j) {
for (size_t i = 0; i < Rows; ++i, ++value) {
grid[i][j] = value;
}
++j;
if (j == Cols )
break;
for (size_t i = Rows; i > 0; ++value) {
--i;
grid[i][j] = value;
}
}
}
template<size_t Rows, size_t Cols>
void zig_zag_fill(int (&grid)[Rows][Cols])
{
int diff_up = 1;
int diff_down = Rows * 2 - 1;
for (size_t i = 0; i < Rows; ++i, diff_down -= 2, diff_up += 2)
{
int value = i + 1;
size_t j = 0;
while ( j < Cols )
{
grid[i][j] = value;
value += diff_down;
++j;
if ( j == Cols )
break;
grid[i][j] = value;
value += diff_up;
++j;
}
}
}
template<size_t Rows, size_t Cols>
void printGrid(int (&grid)[Rows][Cols]) {
for (size_t i = 0; i < Rows; ++i) {
for (size_t j = 0; j < Cols; ++j) {
std::cout << std::setw(2) << grid[i][j] << " ";
}
std::cout << '\n';
}
}
Would output:
1 10 11 20 21 30
2 9 12 19 22 29
3 8 13 18 23 28
4 7 14 17 24 27
5 6 15 16 25 26
1 12 13 24 25
2 11 14 23 26
3 10 15 22 27
4 9 16 21 28
5 8 17 20 29
6 7 18 19 30
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
1 12 13 24 25 36
2 11 14 23 26 35
3 10 15 22 27 34
4 9 16 21 28 33
5 8 17 20 29 32
6 7 18 19 30 31
Firstly, if I was writing this program I would represent my data in a different manner. I.e. I would likely use a vector and avoid global size constants. The being said, here is how I would do this. Let's write out the sequence the indexes follow and try to see if we can create some kind of sequence.
1 4 7
2 5 8
3 6 9
Is what is in your array after creating it and we want
1 6 7
2 5 8
3 4 9
Our indexes to the original array looks like this
(0, 0) (2, 1) (0, 2)
(1, 0) (1, 1) (1, 2)
(2, 0) (0, 1) (2, 2)
Well our j component is easy, it's just a simple arithmetic sequence where you add 1, i.e. 1, 2, 3, 4, 5...
for (int j = 0; j < 3; j++){
...
}
Now we need a sequence that follows the patten 0, 1, 2, 2, 1, 0, 0, 1, 2, ... repeating. Since we have repeating digits, I am thinking of clock arithmetic or modular arithmetic. Let's start with the sequence 0, 1, 2, 0, 1, 2 ... repeating. I.e the integers mod 3 (Z mod 3). For the first column we want the indicies straight up as they are (Z mod 3). Then for the reversed columns let's say we are given this sequence and we are iterating through it from 0 to 2. We can cleverly use modular arithmetic to get to our reversed sequence. For example if we had (2 mod 3), (4 mod 3), (6 mod 3), we would have 2, 1, 0. How do we get 0, 1, 2 to 2, 4, 6? Like this f(x) : (x + 1) * 2.
bool reversed = false;
for (int i = 0; i < 3; i++){
int idx = i;
if(reversed){
int offset = (i + 1) * 2;
idx = (offset) % 3;
}
}
reversed = !reversed;
Now we just have to put it all together. This should be our new init grid as the print function is fine.
for (int j = 0; j < SIZE; j++){
bool reversed = false;
for (int i = 0; i < SIZE; i++){
int idx = i;
if(reversed){
int offset = (i + 1) * (SIZE - 1);
idx = (offset) % SIZE;
}
arr[idx][j] = inc;
inc++;
}
reversed = !reversed;
}
That should do it. I got it to work in repl.it, hopefully this helps.
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
I need to find the mimimum element in two-dimensional(4,4) array by row and maximum element by column and store them in another array (5,5).Maybe I did not explain properly.
That's how it should look new array (5,5):
1 2 3 4 min
1 2 3 4 min
1 2 3 4 min
m m m m 0
*m - max
So this is the first array:
int array[4][4];
int i, j;
for(i = 0; i < 4; i++) {
for(j = 0; j < 4; j++) {
cout << "\n array[" << i + 1 << "][" << j + 1 <<"]=";
cin >> array[i][j];
}
}
With this I try to find the min of each row:
int min;
for (i = 0; i<4; i++) {
min[i] = array[0][i];/*expression must have pointer-to-object type*/
for (j = 1; j<4; j++) {
if (min[i]>array[i][j])/*expression must have pointer-to-object type*/
min[i] = array[i][j];/*expression must have pointer-to-object type*/
}
}
Where I'm wrong? I can't undrestand this error "expression must have pointer-to-object type".
And with this i will try to make new array:
for(i = 0; i < 4; i++) {
for(j = 0; j < 4; j++) {
newarr[i][j]=array[i][j];
newarr[i][5]=max[i];
}
}
for(j = 0; j < 4; j++)
newarr[5][j]=min[j];
Is this okay? There is no way to check it because I just can not find the min and max.
int min;
min[i]
is the source of error. min is an integer variable not an integer array.
change int min to int min[4];
You have int min;. This variable can hold only single value and following is ill-formed min[i], as min is not an array.
Just making it an array should solve the issue: int min[4];
Also note, that first index of 2D array traditionally denotes row and second a column. And check indices usage in your loops: why do you use i as bot first and second index in different places?
Here is shown a straightforward approach. You may use it as a base for your program
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
int main()
{
const int MAX_VALUE = 100;
const size_t N = 4;
int a[N][N];
int b[N+1][N+1];
std::srand( ( unsigned int )std::time( nullptr ) );
for ( auto &row : a )
{
for ( int &x : row ) x = std::rand() % MAX_VALUE;
}
for ( const auto &row : a )
{
for ( int x : row ) std::cout << std::setw( 2 ) << x << ' ';
std::cout << std::endl;
}
std::cout << std::endl;
for ( size_t i = 0; i < N; i++ ) b[N][i] = a[0][i];
b[N][N] = 0;
for ( size_t i = 0; i < N; i++ )
{
int min = a[i][0];
for ( size_t j = 0; j < N; j++ )
{
b[i][j] = a[i][j];
if ( a[i][j] < min ) min = a[i][j];
if ( b[N][j] < b[i][j] ) b[N][j] = b[i][j];
}
b[i][N] = min;
}
for ( const auto &row : b )
{
for ( int x : row ) std::cout << std::setw( 2 ) << x << ' ';
std::cout << std::endl;
}
std::cout << std::endl;
}
The program output might look like
77 53 41 90
67 57 90 94
20 41 29 38
3 72 33 43
77 53 41 90 41
67 57 90 94 57
20 41 29 38 20
3 72 33 43 3
77 72 90 94 0
The idea is to fill the last row of the new array with values of the first row of the original array and then compare each value of the last row with a value of the current row in the current column.
Well that's the whole code:
#include <iostream>
using namespace std;
int main() {
int A[4][4];
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];
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];
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 debuging:
5 4 3 1
5 6 7 9
4 2 3 9
4 8 4 6
0