Home > Software engineering >  Traverse 2D Matrix diagonally omitting first row and first column
Traverse 2D Matrix diagonally omitting first row and first column

Time:05-31

I am trying to traverse a 2D matrix diagonally and the function below prints all elements in a diagonal.I want to skip the first row and first column elements and start the diagonal traversal from matrix[1][1] because the values in the 0th row and 0th column are not required.So it is like slicing the matrix from the top and starting from [1][1] but not making any changes to the bottom of the matrix.

void diagonalOrder(int matrix[][COL])

  {
  
  for(int line = 1;
          line <= (ROW   COL - 1);
          line  )
  {
      int start_col =  max(0, line - ROW);
      int count = min(line, (COL - start_col), ROW);

      /* Print elements of this line */
      for(int j = 0; j < count; j  )
          cout << setw(5) <<
          matrix[minu(ROW, line) - j - 1][start_col   j];

      cout << "\n";
  }

I will update my question with an example to make it clear.Consider the following matrix.

               0 1 2 3 4
matrix[5][5] = 1 8 5 3 1
               2 4 5 7 1
               3 6 4 3 2
               4 3 4 5 6

The above function will print the values of this diagonally.

Output:

0
1 1
2 8 2
3 4 5 3
4 6 5 3 4
3 4 7 1
4 3 1
5 2 
6

I want to skip the elements of the first row and the first column and starting at matrix[1][1] want to traverse the matrix diagonally.

Desired Output: 

8 
4 5
6 5 3
3 4 7 1
4 3 1
5 2 
6

CodePudding user response:

I don't really get what your code is trying to do but just going by the description you need to iterate over the array items with equal row and column indices until there either are no more rows or no more columns i.e.

void print_tail_of_diagonal(int matrix[ROWS][COLS])
{
    int n = std::min(ROWS, COLS);
    for (int i = 1; i < n;   i) {
        std::cout << matrix[i][i] << " ";
    }
    std::cout << "\n";
}

CodePudding user response:

From your example it looks like you want to print antidiagonals not diagonals, ie third line is 3 4 5 3 not 3 5 4 3.

To get started keep things simple: Indices (i,j) along an antidiagonal are those i and j where i j == some_constant. Hence this is a simple (not efficient) way to print elements along one antidiagonal:

void print_antidiagonal(int matrix[5][5],int x){
    for (int i=4;i >= 0; --i) {
        for (int j=0;j < 5;   j) {
            if (i j == x) std::cout << matrix[i][j] << " ";
        }
    }    
    std::cout << "\n";   
}

Further there are nrows (ncols-1) antidiagonals, hence you can print them all via:

for (int i=0;i < 5 4;   i) {
    print_antidiagonal(matrix,i);
} 

The function above isnt very efficient, but it is simple. It is obvious how to skip the first row and first column:

for (int i=4;i >= 1; --i) {         // loop till 1 instead of 0
    for (int j=1;j < 5;   j) {      // loop from 1 instead of 0

This is sufficient to produce desired output (https://godbolt.org/z/7KWjb7qh7). However, not only is the above rather inefficient, but also the code is not very clear about its intent. print_antidiagonal prints elements along a single anti-diagonal, hence iterating all matrix elements is a bad surprise.

I suggest to print the indices rather than the matrix elements to get a better picture of the pattern (https://godbolt.org/z/TnrbbY4jM):

1,1 
2,1 1,2 
3,1 2,2 1,3 
4,1 3,2 2,3 1,4 
4,2 3,3 2,4 
4,3 3,4 
4,4 

Again, in each line i j is a constant. And that constant increments by 1 in each line. In each line i decrements while j increments, until either i == 1 or j==4. The first element is such that i is maximum and j = constant - i.

Hence:

void print_antidiagonal(int matrix[5][5],int x){
    int i = std::min(x-1,4);
    int j = x - i;
    
    while (i >= 1 && j <= 4) {
        std::cout << matrix[i][j] << " ";
        --i;
          j;
    }
    std::cout << "\n";

}

Live Example.

PS: I used hardcoded indices, because I considered it simpler to follow the logic. For a more realistic solution the matrix size and offset should be parametrized of course.

  •  Tags:  
  • c
  • Related