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.
Related
I have made a code that makes this kind of output:
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36
37 38 39 40 41 42
43 44 45 46 47 48
#include <iostream>
using namespace std;
int main() {
// dimensions:
int x=6,y=8;
int sum=0;
int numery[8][6]={};
for (i = 0; i < y; i++) {
for (j = 0; j < x; j++) {
numery[i][j]=++sum;
if (numery[i][j]<=9) cout << " ";
cout << numery[i][j] << " ";
}
cout << endl;
}
return 0;
}
But I don't know how to edit it to get this kind of output:
6 5 4 3 2 1
7 8 9 10 11 12
18 17 16 15 14 13
19 20 21 22 23 24
30 29 28 27 26 25
31 32 33 34 35 36
37 38 39 40 41 42
43 44 45 46 47 48
I can think of making if statement for each i%2==1 that it should go backwards, but I don't know how to make program do such thing. Otherwise it should go normally. So if it find an even row it should go like 7 8 9 10 11 12, whereas if it's i%2==1 it should go like 6 5 4 3 2 1 and so on.
Some suggestions?
One solution would be the following (I assume that you do not really need to store the numbers). Notice that setw() can be used to print the numbers with fixed width:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
// dimensions:
int x=6,y=8;
for (int i = 0; i < y; i++)
{
for (int j = 0; j < x; j++)
{
cout << setw(3) << ((i%2) ? i*x+j+1 : i*x+x-j) << " ";
}
cout << endl;
}
return 0;
}
First get rid of the array. It is unnecessary.
#include <iostream>
using namespace std;
int number(int i,int j,int width) { return j+i*width +1 ;}
int main() {
// dimensions:
int x=6,y=8;
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
auto n = number(i,j,x);
if (n <= 9) cout << " ";
cout << n << " ";
}
cout << endl;
}
return 0;
}
This has same output as your code.
Next consider what happens to j when you go reverse. You should think that through, the answer is: You replace j with width-j-1.
int number_reverse(int i,int j, int width) { return number(i,width-j-1,width); }
Eventually you just need to call the right function in each iteration of the outer loop:
#include <iostream>
using namespace std;
int number(int i,int j,int width) { return j+i*width +1 ;}
int number_reverse(int i,int j, int width) { return number(i,width-j-1,width); }
int main() {
// dimensions:
int x=6,y=8;
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
auto n = (i%2) ? number_reverse(i,j,x) : number(i,j,x);
if (n <= 9) cout << " ";
cout << n << " ";
}
cout << endl;
}
return 0;
}
Here is a solution in case you DO need to store the numbers in an array.
#include <iostream>
using namespace std;
int main() {
// dimensions:
int x=6,y=8;
int sum=0;
int numery[y][x];
for (int i = 0; i < y; i++)
for (int j = 0; j < x; j++)
numery[i][j]=++sum;
for(int i = 0; i < y; i++)
{
if(i%2 == 0)
{
for(int j = x-1; j >= 0; --j)
{
if(numery[i][j] < 10)
{
cout << " ";
}
cout << numery[i][j] << " ";
}
cout << endl;
}
else
{
for(int j = 0; j < x; j++)
{
if(numery[i][j] < 10)
{
cout << " ";
}
cout << numery[i][j] << " ";
}
cout << endl;
}
}
return 0;
}
you assign the numbers to your array first. then you print the numbers from back-to-front or front-to-back based on if are on an even or odd row.
If you are willing to fill the array in non-linear order, you can fill every second line from right to left: array[i][x-1-j]=++sum;.
Another approach is to use one outer loop and two inner loops, noticing that all the rows are of form a*i + b*j + c, where b is either +1 or -1. This simplifies to array[i][j] = 6*i + 6 - j for even rows and to array[i][j]=6*i + 1 + j for the odd rows.
One more option is to have a single inner loop, which will increase or decrease by some amount d = i % 2 == 0 ? -1 : 1;
for (int j = 0; j<x; j++) { arr[i][j]=sum; sum += d;}
sum+=6-d;
After each row we need to compensate the variable sum so that it begins with the correct value for the next index i+1.
I want to make a program that converts an array into matrix. I made something that sort of works but I'm not quite satisfied with the result. I am getting output that actually makes sense but I don't know what I should change to get the one I want.
The size of matrix doesn't have to be 4x4 it can be whatever in fact I want to make one that can make me a 4x4 out of an array[15].
#include<iostream>
#include<vector>
#include<ctime>
#include<cstdlib>
typedef unsigned int uint;
void print(const std::vector<int>& array)
{
for(uint i=0; i< array.size(); i++)
std::cout << array[i] << " ";
std::cout << "\n" << std::endl;
}
void random(std::vector<int>& array, int size = 4)
{
srand(time(0));
std::vector<std::vector<int>> mat;
for(uint i=0; i<4; i++)
{
for(uint j=0; j<4; j++)
{
array.push_back(rand()%10);
}
mat.push_back(array);
}
print(array);
for(uint i=0; i<4; i++)
{
for(uint j=0; j<4; j++)
{
std::cout << mat[i][j] << " ";
}
std::cout << std::endl;
}
}
main()
{
std::vector<int> A;
random(A);
}
Example of an output since it's random
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
The one i would like to get would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
After you've added array to mat with mat.push_back(array), you need to clear array, otherways array will always grow.
std::vector<std::vector<int>> mat;
for (uint i = 0; i < 4; i++)
{
for (uint j = 0; j < 4; j++)
{
array.push_back(rand() % 10);
}
mat.push_back(array);
array.clear(); // <<<< add this
}
Change the code that prints mat to this:
for (uint i = 0; i < mat.size(); i++)
{
for (uint j = 0; j < mat[i].size(); j++)
{
std::cout << mat[i][j] << " ";
}
std::cout << std::endl;
}
and you'll see what happens if you don't call array.clear() as shown above.
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.
I am having trouble with making a turn inside a two dimensional array to output the elements in spiral. I tried this code, but it is outputting not enough elements, I tried to make some if statements outside of the loop to cover all cases for which the general algorithm doesn't output. Can you help suggesting some way to manage the correct output.
CODE
#include <iostream>
#include <algorithm>
//#include <cmath>
using namespace std;
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int r, c;
cin >> r >> c;
int r_beg = 0, r_end = r - 1, c_beg = 0, c_end = c - 1;
int **m = new int*[r];
for (int i = 0; i < r; i++)
{
m[i] = new int[c];
for (int j = 0; j < c; j++)
{
cin >> m[i][j];
}
}
for (int runs = min(r, c) / 2; runs--;) {
for (int i = c_beg; i < c_end; i++)
cout << m[r_beg][i] << " ";
for (int i = r_beg; i < r_end; i++)
cout << m[i][c_end] << " ";
for (int i = c_end; i > c_beg; i--)
cout << m[r_end][i] << " ";
for (int i = r_end; i > r_beg; i--)
cout << m[i][c_beg] << " ";
r_beg++;
c_beg++;
r_end--;
c_end--;
}
if (r <= c && c_beg <= c_end) {
for (int i = c_beg; i <= c_end; i++)
cout << m[r_end][i] << " ";
}
else if (r >= c && r_beg <= r_end) {
for (int i = r_beg; i <= r_end; i++)
cout << m[i][c_end] << " ";
}
for (int i = 0; i < r; i++)
delete[] m[i];
delete[] m;
return 0;
}
Example:
Input:
3 3
1 2 3
4 5 6
7 8 9
Output: 1 2 3 6 9 8 7 4 5
If you have for example 3x10 matrix. It doesn't output.
Input:
3
7
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
Output: should get to 13, but it stops at 8.
The code, as presented, loops towards center until the smaller of the two dimensions is consumed up. However, if that smaller dimension has odd size, then parts of the central row or column respectively haven't been printed out. You can cover that one with some special case handling after your outer loop:
for (int runs = std::min(r, c) / 2; runs--;)
{
// ...
}
if(c < r)
{
if(c & 1)
{
for (int i = r_beg; i <= r_end; i++)
// ^ (!)
// don't forget to print last element: there's no second loop
// that would print the corner element a second time now!
std::cout << m[i][c_end] << " ";
}
}
else
{
// handles the square matrix case as well
if(r & 1)
{
for (int i = c_beg; i <= c_end; i++)
std::cout << m[r_beg][i] << " ";
}
}
This can be solved by carefully fine-tuning the bail-out conditions / ranges of the for loops:
#include <iostream>
using namespace std; // :-(
int main() {
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int r, c;
cin >> r >> c;
int r_beg = 0, r_end = r - 1, c_beg = 0, c_end = c - 1;
int **m = new int*[r];
for (int i = 0; i < r; i++)
{
m[i] = new int[c];
for (int j = 0; j < c; j++)
{
cin >> m[i][j];
}
}
for (int runs = min(r, c);;)
{
for (int i = c_beg; i <= c_end; i++)
cout << " " << m[r_beg][i];
++r_beg;
for (int i = r_beg; i <= r_end; i++)
cout << " " << m[i][c_end];
--c_end;
if (!--runs) break;
for (int i = c_end; i >= c_beg; i--)
cout << " " << m[r_end][i];
--r_end;
for (int i = r_end; i >= r_beg; i--)
cout << " " << m[i][c_beg];
++c_beg;
if (!--runs) break;
}
for (int i = 0; i < r; i++)
delete[] m[i];
delete[] m;
return 0;
}
Input:
3 7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Output:
1 2 3 4 5 6 7 14 21 20 19 18 17 16 15 8 9 10 11 12 13
Live Demo on ideone
Input:
4 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Output:
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
Notes:
I changed the bail-out of the for loop:
Instead of min(r, c) / 2, I use min(r, c) and decrement/check runs twice in the body.
I adjusted the update of r_beg, r_end, c_beg, and c_end.
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.