**Section 6 - Multidimensional arrays
**

-All the same rule for 1D arrays hold here: can't print the whole array with cout <<, unless you overload <<; can't assign one array to another, unless you overload =; etc.

-There is no limit to the number of dimensions
defined

**-Two-dimensional arrays**

-Think of these as a matrix or a grid

-for an NxM array, each row is numbered 0 to N-1 and each column is numbered from 0 to M-1

-e.g. a 5x4 matrix:

0
| 1 | 2
| 3 | |

0 | 12 | 3 | 23 | 54 |

1 | 6 | 5 | 87 | 76 |

2 | 32 | 45 | 54 | 37 |

3 | 7 | 8 | 4 | 65 |

4 | 3 | 45 | 55 | 42 |

-to declare such a structure in C++:

`const int`

` NumRows = 5,`

` NumCols = 4;
`

`int`

` Matrix[NumRows][NumCols];
`

-and to access any particular element:

`Matrix[0][0] //12`

`Matrix[4][3] //42`

`etc.`

`-each of these is a single
integer!
`

-extended example:

-suppose we had to track daily temperatures for 4 weeks - w/o 2D array, we'd need 4 arrays of 7 days each

-instead, we can do this:

`float`

` Temps[4][7];
`

-with this definition, we can process a month's worth of data at once:

-getting the temps from a file:

`for (r=0; r<4; r++)`

` for(c=0; c<7; c++)`

` Instream >> Temps[r][c];
`

-printing out in four rows:

`for (r=0; r<4; r++)`

` {`

` for (c=0; c<7; c++)`

` Outstream << Temps[r][c];`

` Outstream << endl;`

` }
`

-To better facilitate readability and ease
of use, we can declare a data type of our array type, using the
*typedef* specifier:

`typedef float TempMatrix[4][7];`

`TempMatrix //declare an array of type tempmatrix`

` Temps;
`

-Then, to pass the variable to a function, you don't need the [ ]'s, since the data type IS an array:

`void PrintTemps(TempMatrix Temps; fstream& out)`

`{`

`etc.`

`}
`

-We could further add to readability by using enumerated types as the indices:

`enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat, NumDays};`

`enum Weeks {Week1,Week2,Week3,Week4,NumWeeks};`

`typedef float TempMatrix[NumWeeks][NumDays];`

`TempMatrix //declare an array of type tempmatrix`

` Temps;`

`. . .`

`Temps[Week1][Sun] //much clearer than Temps[0][0]
`

-of course, you'd have to create functions
to work with the enumerated types, for incrementing, etc. - but
in the long run, it makes the program much better

-Suppose we wanted to find the average temperature
for each week- we'd want a function to do this, but we'd have
to pass the entire 2D array, and the week number to average, or
we'd have to pass 7 pieces of the array: Temps[Week1][Sun], Temps[Week1][Mon],
etc.

UGH!

-It would be nicer if we could just pass a week as a whole entity,
but the array is not defined that way - BUT WE CAN DEFINE IT THAT
WAY!

-Think of defining the 2D array as a 4 element array (4 weeks) and each element is an array (7 days) - an array of arrays!

`enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat, NumDays};`

`//now define a data type of an array of 7 days`

`typedef float TempList[NumDays];`

`enum Weeks {Week1,Week2,Week3,Week4,NumWeeks};`

`//now define a data type of an array of 4 weeks`

`typedef TempList TempMatrix[NumWeeks];`

`//now declare a variable of type TempMatrix (an array of arrays)`

`TempMatrix`

` Temps;
`

-This implies that the following:

`Temps[Week1]`

IS a 7 element array! It is a variable of type Weeks!

-so our function to average the temperatures for one week looks like this:

`double WeekAvg(Weeks Aweek)`

`{`

`double sum=0.0;`

`for (Day d=Sun; d<=Sat; d++) //overloaded ++`

` Sum += Aweek[d];`

`return Sum/NumDays;`

`}//end function
`

and the call looks like this:

`WkAvg = WeekAvg(Temps[Week1]);
`

-With this type of definition, you could even swap rows (given swap overload definition):

`Swap(Temps[Week1],Temps[Week2]);`

-What would swap definition look like??

-What if we wanted to swap columns?? (given an array of arrays definition)

`void SwapColums(TempMatrix Mat, Day d1, Day d2)`

`//pass in whole array and column values (days) of columns
to swap`

`{`

`for (Week w=Week1; w < NumWeeks; w++) //overloaded ++
Swap(Mat[w][d1], Mat[w,d2]); //real
# swap!`

`}
`

-A similar algorithm would be needed to swap
rows if matrix had not been defined as array of arrays

-When program is modeling data which uses a
matrix row as an entity, it may be beneficial to use the "array
of arrays" definition. Otherwise, the simple definition
is better, and easier to understand

-reviewing the difference in declaration (w/o enumerated types):

-this is 'simple' matrix:

`typedef double Matrix[NumRows][NumCols] //constants defined
elsewhere`

`Matrix`

` Mat;
`

-this is the array of arrays:

`typedef double Row[NumCols]; //an array of type double `

`typedef Row Matrix[NumRows]; //an array of type Row`

`Matrix
Mat;
`

**-practice (using the above 'simple' type):**

- -Read in numbers from file and fill matrix (don't read too many!)
- -Compute the product of the row sums (i.e., sum the rows and multiply these sums)
- -Compute the sum of the row products (i.e., multiply the row values and sum these products)
- -Compute the product of the column sums
- -Compute the sum of the column products
- -Print in matrix (row by row) format
- -Print the Nth row or column of matrix (given N)
- -Print the left (downward) or right (upward) diagonal of a square matrix

(Using the array of arrays declaration, #s
2 and 3 could be made simpler by using a function to compute the
sum of the row elements and the product of the row elements, passing
an entire row to these functions)

-Template for #2 and #3:

`product = 1; //sum=0 for #3`

`for (r=0; r<NumRows; r++)
{
sum = 0; `

` for (c=0; c<NumCols; c++)`

` sum += Mat[r][c]; //product*=Mat[r][c]
for #3`

` product *= sum; //sum += product
for #3`

` }
`

- work out others on own

-Initializing 2D arrays - just like single-D arrays:

`int `

` Matrix[4][3] = {9,8,7,6,5,4,3,2,1,0,1,2}; //12 values (4X3)
`

-to make it clearer, can show rows/columns:

`int`

` Matrix[4][3] = {{9,8,7},
(6,5,4},
{3,2,1},
{0,1,2}};
`

-As with 1D arrays, initializing a numeric
array with fewer than the required elements will result in the
remaining elements defaulting to 0

**-Multidimensional arrays**

-you can define any number of dimensions of arrays - whatever is required of the problem

-for example, our temperature matrix, suppose we wanted to track a year's worth of temperatures (per month) - could declare 12 separate matrices, one per month, but that is very clunky - instead, create a 3D array (i.e., an array of matrices!)

-e.g.:

`enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat, NumDays};`

`enum Weeks {Week1,Week2,Week3,Week4,NumWeeks};`

`enum Months {Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NumMonths};`

`//now define a data type of an array of 7 days`

`typedef float TempList[NumDays];`

`//now define a data type of an array of 4 weeks`

`typedef TempList TempMatrix[NumWeeks];`

`//now define a data type of an array of 12 months`

`typedef TempMatrix Year[NumMonths];`

`//now declare a variable of type Year (an array of arrays
of arrays)`

`Year`

` Temps;
`

`//ALTERNATE DEFINITION, THAT DOESN'T USE ARRAY-OF-ARRAYS STRUCTURE:`

`float`

` Temps [NumMonths][NumWeeks][NumDays];`

`//but this would be awkward to pass as parameter
`

`To access a given day:`

`Temps[Jan][Week1][Mon]`

`Temps[Dec][Week4][Sat]
`

`Function prototype (using array of array type):`

`void PrintArray(Year Temps);
`

`Comparing two days' temperatures:`

`if (Temps[Jan][Week2][Tue] > Temps[Dec][Week2][Wed])`

` etc.
`

`Here's the function to fill entire array:`

`void GetTemps(Year Temps, fstream& Infile)`

`{`

`for (Months M=Jan; M<=Dec; M++) //++ overloaded for type
Months`

` for(Weeks W=Week1; W<=Week4; W++) //++ overloaded for
type Weeks`

` for(Days D=Sun; D<=Sat; D++) //++ overloaded for type
Days`

` Infile >> Temps[M][W][D]; //read in one real #
into array`

`}//end function
`

**-Other practice routines for 3D arrays:**

-Print out entire array in "nice"
format

-Find average yearly temp

-Find average monthly temp

-Find average daily temp

-Find highest or lowest daily temp

**-4D arrays**

-declaring 4D array (not array of array format)

`typedef float Time[40][10][10][10];`

`Time`

` Stats;
`

`Stats[p][q][r][s] //one real number
`