Problem Solving: Matrix Traversals II
Learn to solve different matrix problems of reshaping and traversals.
Diagonal traversals and mappings from to R dimensional world
In this lesson, we will learn several new non-trivial mapping techniques.
Your implementation
Use the following playground for writing the code and testing it.
#include <iostream> using namespace std; #define MaxR 100 #define MaxC 100 #define Capacity 1000 void diagonalMapping1(int TDA[MaxR][MaxC], int rows, int cols, int projectionMap[Capacity], int &size) { // Write your code here. } void diagonalMapping2(int TDA[MaxR][MaxC], int rows, int cols, int projectionMap[Capacity], int &size) { // Write your code here. } void diagonalMapping3(int TDA[MaxR][MaxC], int rows, int cols, int projectionMap[Capacity], int &size) { // Write your code here. } void print2DWorld(const char Msg[], int TDA[MaxR][MaxC], int rows, int cols) { cout << Msg; for(int ri=0; ri<rows; ri++) { for(int ci=0; ci<cols; ci++) { cout << TDA[ri][ci]<<" "; } cout << endl; } } void print1DProjection(const char Msg[], int projectionMap[Capacity], int size) { cout << Msg; for(int mi=0; mi<size; mi++) { cout << projectionMap[mi]<<" "; } } int main() { int TDA[MaxR][MaxC] = {{1,2,3},{4,5,6},{7,8,9}}, rows=3, cols=3; int projectionMap[Capacity], size; print2DWorld("Two Dimensional World\n", TDA, rows, cols); diagonalMapping1(TDA, rows, cols, projectionMap, size); print1DProjection("\n\nProjected World\n", projectionMap, size); diagonalMapping2(TDA, rows, cols, projectionMap, size); print1DProjection("\n\nProjected World\n", projectionMap, size); diagonalMapping3(TDA, rows, cols, projectionMap, size); print1DProjection("\n\nProjected World\n", projectionMap, size); return 0; }
Diagonal mapping I
Look at the mapping case below in which every diagonal traverses from left to right and bottom to top.
Look at the illustration and understand it before we move forward.
How to map
Look at the animation below carefully. The first upper half of the diagonals, including the middle diagonal (1st, 2nd, and the 3rd), start from the 0th column, and the starting row of each diagonal is one more than the previous diagonal, respectively. The lower half of the diagonals (4th, 5th, and 6th) always start from the last row, and the starting column of each lower diagonal is 1 more than the previous, respectively. Lastly, in each diagonal, the row decreases by 1, and the column increases by 1.
Implementation details
Here are the algorithmic details:
- Initialized
ai
with0
, whereai
is the mapping index of the one-dimensional array. - The first nested loop (for printing upper diagonals):
- For each diagonal
d
from0
torows-1
, because there arerows
many upper diagonals:- For each pair
r=d
(thed
th diagonal starts fromd
th row),c=0
(each diagonal starts from0
th column), row should be equal or greater than zeror>=0
and the row will decrementr--
and column will incrementc++
in each step. Note: In all these upper diagonals, the row value, thus the boundary condition is that the row value must be greater than or equal to0
(r>=0
).- Update the 1-D array
projectionMap[ai]
withTDA[ri][ci]
with an increment inai
.
- Update the 1-D array
- For each pair
- For each diagonal
- The second nested loop (for printing lower diagonals).
- For each diagonal
d
from1
tocols-1
, as there are total ofcols-1
lower diagonals.- For each pair (
r=rows-1
,c=d
):- Update the 1-D array
projectionMap[ai]
withTDA[ri][ci]
with an increment inai
. - The row will decrement
r--
and the column will incrementc++
, and the column index should be bounded byc<cols
.
- Update the 1-D array
- For each pair (
- For each diagonal
Instruction: Understand the code below, rewrite it in your playground, and test it.
void diagonalMapping1(int TDA[maxR][maxC], int rows, int cols, int projectionMap[capacity], int &size){int ai=0;size = rows*cols;for(int d=0; d<rows; d++){for(int r=d, c=0; r>=0; r--, c++){projectionMap[ai] = TDA[r][c];ai++;}}for(int d=1; d<cols; d++){for(int r=rows-1,c=d; c<cols; r--, c++){projectionMap[ai] = TDA[r][c];ai++;}}}
Exercise 1: Diagonal mapping II
Look at the mapping case below in which we traverse diagonally from left to right. Understand it before we move forward.
How to map
Look at the animation below carefully. The first upper half of the diagonals, including the middle diagonal (1st, 2nd, and 3rd), start from the 0th row, and the starting column of each diagonal is one more than the previous diagonal, respectively. The lower half of the diagonals (4th, 5th, and 6th) always start from the last column, and the starting row of each lower diagonal is 1 more than the previous, respectively. Lastly, in each diagonal, the row increases by 1, and the column decreases by 1.
Instruction: Write the code in your playground and test it. If you are stuck, look at the hint.
Exercise 2: Diagonal mapping III
Look at the case below where each even diagonal is traversing from left to right and in an upward direction and odd arrows right to left and in a downward direction.
How to map
The first thing we need to notice is that this mapping is a merge of the above two mappings such that the even diagonal (0th, 2nd, and so on) are moving from left to right and in upward directions, and in the odd case the diagonal is moving from right to left and downwards.
Alternative the even and the odd cases can be managed by maintaining one boolean variable. And toggling the state of this flag is just one line:
bool isEven = true/false;
.
.
isEven=!isEven; // toggling the state.
All we need to do is the following:
- Again, we will print in two separate nested loops: one for the upper half and one for the lower half.
- In both nested loops, in the case of the even diagonal
mapping1()
should get activated andmapping2()
otherwise.
The complete code of the three diagonal mapping functions
Here is the complete implementation of the three diagonal mapping functions.
#include <iostream> using namespace std; #define MaxR 100 #define MaxC 100 #define Capacity 1000 void diagonalMapping1(int TDA[MaxR][MaxC], int rows, int cols, int projectionMap[Capacity], int &size); void diagonalMapping2(int TDA[MaxR][MaxC], int rows, int cols, int projectionMap[Capacity], int &size); void diagonalMapping3(int TDA[MaxR][MaxC], int rows, int cols, int projectionMap[Capacity], int &size); void print2DWorld(const char Msg[], int TDA[MaxR][MaxC], int rows, int cols); void print1DProjection(const char Msg[], int projectionMap[Capacity], int size); int main() { int TDA[MaxR][MaxC] = {{1,2,3},{4,5,6},{7,8,9}}, rows=3, cols=3; int projectionMap[Capacity], size; print2DWorld("Two Dimensional World\n", TDA, rows, cols); diagonalMapping1(TDA, rows, cols, projectionMap, size); print1DProjection("\n\nProjected World\n", projectionMap, size); diagonalMapping2(TDA, rows, cols, projectionMap, size); print1DProjection("\n\nProjected World\n", projectionMap, size); diagonalMapping3(TDA, rows, cols, projectionMap, size); print1DProjection("\n\nProjected World\n", projectionMap, size); return 0; }