C++: Process 2d array elements in a diagonal fashion
Let's say we have a two dimensional arrays, arr[N][N]
, where N
is a constant integer
.
Assume that every element of arr
is initialized.
How do I print the elements of arr
antidiagonal-wise using nested for loops?
What I mean is:
- After first iterati开发者_如何学运维on of the outer-most loop,
arr[0][0]
will be printed - After second iteration of the outer-most loop,
arr[0][1]
andarr[1][0]
will be printed - After third iteration of the outer-most loop,
arr[0][2]
,arr[1][1]
, andarr[2][0]
will be printed - ...
- After the last iteration of the outer-most loop,
arr[N-1][N-1]
will be printed.
Thanks for your time!
Sorry to everybody who wrote "The second half should be similar"... it's not.
Anyway, here you go:
// traverse array diagonally
int c, tmp, x;
for (c = N - 1; c > -N; c--) {
tmp = N - abs(c) - 1;
x = tmp;
while (x >= 0) {
if (c >= 0) {
std::cout << arr[x][tmp - x] << ", ";
}
else {
std::cout << arr[N - (tmp - x) - 1][(N-1)-x] << ", ";
}
--x;
}
std::cout << "\n";
}
Do you need this for a game or something?
[edit] looking at this again, I think my answer wasn't very nicely written. Here's a quick run through:
Let's pretend that N is 3.
What we need is an iteration over coordinate-combinations that looks like this:
(0, 0)
(1, 0), (0, 1)
(2, 0), (1, 1), (0, 2)
(2, 1), (1, 2)
(2, 2)
So first some placeholders:
int c, // a counter, set by the outer loop
tmp, // for intermediate results
x; // the x-index into *arr* (*y* will be defined implicitly)
Now this outer loop
for (c = N - 1; c > -N; c--) {
makes c iterate over {2, 1, 0, -1, 2}.
The next step
tmp = N - abs(c) - 1;
x = tmp;
turns {2, 1, 0, -1, -2} into {0, 1, 2, 1, 0}, which are the lengths of the needed outputs at this step minus one (so they can be used as indices). We make two copies of this, tmp and x.
Now we count down from x to 0:
while (x >= 0) {
...
--x;
}
if we're on the upper-left half of arr, indicated by c >= 0, the x-indices into arr need to start at the diagonal and go down to zero (0 to 0, 1 to 0 and 2 to 0) , whereas the y-indices need to start at zero and go up to the diagonal (0 to 0, 0 to 1 and 0 to 2):
if (c >= 0) {
std::cout << arr[x][tmp - x] << ", ";
}
once we're on the lower-right half, the x-indices need to start at N and to down to the diagonal (2 to 1 and 2 to 2), whereas the y-indices need to start at the diagonal and go up to N (1 to 2 and 2 to 2):
else {
std::cout << arr[N - (tmp - x) - 1][(N-1)-x] << ", ";
}
finally we just need a line-break at the end of each line:
std::cout << "\n";
Savy? :-)
This will work for half the matrix.. the other half will be similar:
for (j = 0 ; j < N ; j++)
{
for (i = 0 ; i <= j ; i ++)
{
printf("%d \n",a[i,j-i]);
}
}
You can notice that for any diagonal, 2 "adjacent" elements are given by [x][y]
and [x+1][y-1]
: that is, you take a diagonal step to the right and up.
So you can have a loop that sets the first cell of the diagonal. You only need to iterate through all values of y
, starting at [0][y]
, and then do this right-up step (diagonally) until you hit the top side or the right side. Then you will need to do the same by moving across from [0][N-1]
to [N-1][N-1]
to cover the second half.
Code follows:
for (int _y = 0; _y < N; _y++) {
int x = 0, y = _y;
while (x < N && y >= 0) {
cout << arr[x][y];
x++; y--;
}
cout << endl; // don't forget a newline
}
I am going to leave out the second half of the code, because it should be about the same.
Here is a snippet of java code, but the algo is the same
for(int i = 0; i < 10; i++){
for(int j = 0; j <= i; j++){
System.out.print(a[j][i-j] + " ");
}
System.out.println();
}
Looks something like this:
for(row = 0; row < N; row++){
for(j = 0; j <= row; j++){
print Array[row - j][j];
}
newline;
}
Here is the solution for both halves of the matrix:
//First half (including middle diagonal)
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
print array[j][i - j];
}
newline;
}
//Second half (excluding middle diagonal)
for (int i = n - 1; i >= 0; i--) {
for (int j = 0; j < i; j++) {
print array[n - i + j][n - j - 1];
}
newline;
}
Here Is One Solution I think Its Helpful R is Total Number of Row.
void diagonalOrder(int arr[][COLS],int R)
{
for (int i = 0; i < R+COLS-1; i++)
{
int col;
int row;
i<COLS?col=i:col=(COLS-1);
col>i?row=col-i:row=i-col;
for(int j=col;j>=0 ;j--)
{
if(row<R)
cout<<arr[row][j]<<" ";
row++;
}
cout<<endl;
}
}
ie.
const int ROWS = 4;
const int COLS = 3;
int arr[][COLS] = {{ 1, 2, 4 },
{ 3, 5, 7},
{ 6, 8, 10},
{ 9, 11, 12}
};
diagonalOrder(arr,ROWS);
Output
----------
1
2 3
4 5 6
7 8 9
10 11
12
------------------------------------------------------
const int ROWS = 8;
const int COLS = 3;
int arr8[][COLS] = {{ 1, 2, 4 },
{ 3, 5, 7 },
{ 6, 8, 10 },
{ 9, 11, 13 },
{ 12, 14, 16},
{ 15 ,17, 19},
{ 18 ,20, 22},
{ 21, 23, 24}
};
cout<<"\n\n8*3 Matrix"<<endl<<endl;
diagonalOrder(arr8,8);
--------------------------------------------------------------
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
-----------------------------------------
int arr[][COLS] = {{ 1, 2, 4 ,20},
{ 3, 5, 7,20},
{ 6, 8, 10,20},
{ 9, 11, 12,20}
};
-------------------------------------------------------------
Output
-------------------------------------------------------------
1
2 3
4 5 6
20 7 8 9
20 10 11
20 12
20
You can work with n*n Matrix ..
精彩评论