Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 iteration of the outer-most loop, arr[0][0] will be printed
  • After second iteration of the outer-most loop, arr[0][1] and arr[1][0] will be printed
  • After third iteration of the outer-most loop, arr[0][2], arr[1][1], and arr[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!

like image 286
Demi Avatar asked Dec 28 '22 19:12

Demi


2 Answers

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? :-)

like image 158
HumanCatfood Avatar answered Jan 14 '23 09:01

HumanCatfood


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]);
   }
}
like image 22
Yochai Timmer Avatar answered Jan 14 '23 09:01

Yochai Timmer