2. Week 8: Multidimensional Arrays
Week8 - 2
Objectives:
Understand the concept and application of
multidimensional arrays
Reference:
Chapter 6: Numeric Arrays
3. 1. One-Dimensional Arrays (1/2)
Array
A collection of
data, called
elements, of
homogeneous
type
Week8 - 3
a
Array name
int
Element type
[6]
Array size
12 25
20 8 36 9
a[0] a[1] a[2] a[3] a[4] a[5]
4. 1. One-Dimensional Arrays (2/2)
Week8 - 4
Preparing an array prior to processing:
int main(void) {
int numbers[] = { 20, 12, 25, 8, 36, 9 };
...
}
Initialization (if values are known beforehand):
int main(void) {
int numbers[6], i;
for (i = 0; i < 6; i++)
scanf("%d", &numbers[i]);
...
}
Or, read data into array:
some_fn(numbers, 6);
some_fn(numbers, 6);
5. 1.1 Print Array
Week8 - 5
void printArray(int arr[], int size) {
int i;
for (i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("n");
}
int main(void) {
int numbers[6];
...
printArray(numbers, 6);
printArray(numbers, 3);
}
Calling:
Print first 6 elements (all)
Print first 3 elements
Value must not
exceed actual
array size.
6. 1.2 Find Maximum Value
Week8 - 6
int findMax(int arr[], int size) {
int i, max;
max = arr[0];
for (i = 1; i < size; i++)
if (arr[i] > max)
max = arr[i];
return max;
}
findMax(int arr[], int size) to return the maximum value in
arr with size elements
Precond: size > 0
i
1
max
20
12
25
8
36
9
20
arr
2
3
4
5 25
36
6
7. 1.3 Sum Elements
Week8 - 7
int sum(int arr[], int size) {
int i, sum = 0;
for (i = 0; i < size; i++)
sum += arr[i];
return sum;
}
sum(int arr[], int size) to return the sum of elements
Precond: size > 0
i sum
0
12
25
8
36
9
20
arr
20
32
57
0
1
2
3 65
4 101
5 110
6
8. 1.4 Sum Alternate Elements
Week8 - 8
int sum(int arr[], int size) {
int i, sum = 0;
for (i = 0; i < size; i++)
sum += arr[i];
return sum;
}
sumAlt(int arr[], int size) to return the sum of alternate
elements (1st
, 3rd
, 5th
, etc.)
Precond: size > 0
i sum
0
12
25
8
36
9
20
arr
20
45
81
0
2
4
6
int sumAlt(int arr[], int size) {
int i, sum = 0;
for (i = 0; i < size; i+=2)
sum += arr[i];
return sum;
}
9. 1.5 Sum Odd Elements
Week8 - 9
int sum(int arr[], int size) {
int i, sum = 0;
for (i = 0; i < size; i++)
sum += arr[i];
return sum;
}
sumOdd(int arr[], int size) to return the sum of elements
that are odd numbers
Precond: size > 0
i sum
0
12
25
8
36
9
20
arr
25
0
1
2
3
4
5 34
6
int sumOdd(int arr[], int size) {
int i, sum = 0;
for (i = 0; i < size; i++)
if (arr[i]%2 == 1)
sum += arr[i];
return sum;
}
10. 1.6 Sum Last 3 Elements (1/3)
Week8 - 10
sumLast3(int arr[], int size) to return the sum of the last 3
elements among size elements
Precond: size >= 0
Examples
numbers sumLast3(numbers, size)
{ } 0
{ 5 } 5
{ 12, -3 } 9
{ 20, 12, 25, 8, 36, 9 } 53
{ -1, 2, -3, 4, -5, 6, -7, 8,
9, 10 }
27
11. 1.6 Sum Last 3 Elements (2/3)
Week8 - 11
Thinking…
Last 3 elements of an array arr
arr[size – 1]
arr[size – 2]
arr[size – 3]
A loop to iterate 3 times (hence,
need a counter) with index
starting at size – 1 and
decrementing in each iteration
int i, count = 0;
for (i = size - 1; count<3; i--) {
. . .
count++;
}
But what if there are fewer than 3
elements in arr?
int i, count = 0;
for (i = size - 1; (i >= 0) && (count<3) ; i--) {
. . .
count++;
}
12. 1.6 Sum Last 3 Elements (3/3)
Week8 - 12
int sumLast3(int arr[], int size) {
int i, count = 0, sum = 0;
for (i = size - 1; (i >= 0) && (count<3); i--) {
sum += arr[i];
count++;
}
return sum;
}
13. 1.7 Minimum Pair Difference (1/3)
Week8 - 13
All problems on 1D arrays can be solved by single loop? Of
course not!
Write a function minPairDiff(int arr[], int size) that computes
the minimum possible difference of any pair of elements in
arr.
For simplicity, assume size > 1 (at least 2 elements in array).
numbers minPairDiff(numbers, size)
{ 20, 12, 25, 8, 36, 9 } 1
{ 431, 945, 64, 841, 783,
107, 598 }
43
14. 1.7 Minimum Pair Difference (2/3)
Week8 - 14
Thinking… Eg: size = 5. Need to compute difference of
arr[0]
arr[1]
arr[2]
arr[3]
arr[4]
arr[1]
arr[2]
arr[3]
arr[4]
arr[2]
arr[3]
arr[4]
arr[3] arr[4]
Outer loop index
i from 0 to size-2
Inner loop index
j from 1 to size-1
Inner loop index
j from 2 to size-1
Inner loop index
j from 3 to size-1
Inner loop index
j from 4 to size-1
Inner loop index
j from i+1 to size-1
15. 1.7 Minimum Pair Difference (3/3)
Week8 - 15
Outer loop index
i from 0 to size-2
Inner loop index
j from i+1 to size-1
int minPairDiff(int arr[], int size) {
int i, j, diff, minDiff;
minDiff = abs(arr[0] – arr[1]); // init min diff.
for (i = 0; i < size-1; i++)
for (j = i+1; j < size; j++) {
diff = abs(arr[i] – arr[j]);
if (diff < minDiff)
minDiff = diff;
}
return minDiff;
}
The code…
16. Codes Provided
Week8 - 16
Week8_FindMax.c:
Section 1.2 Find Maximum Element
Week8_SumElements.c:
Section 1.3 Sum Elements
Section 1.4 Sum Alternate Elements
Section 1.5 Sum Odd Elements
Section 1.6 Sum Last 3 Elements
Week8_MinPairDiff.c:
Section 1.7 Minimum Pair Difference
17. 1.8 Accessing Array Elements in Function (1/2)
Week8 - 17
Why is it not necessary to
have a value in here to
indicate the “real” size?
A function header with array parameter,
int sum(int a[ ], int size)
A value is not necessary (and is ignored by compiler if provided) as
accessing a particular array element requires only the following
information
The address of the first element of the array
The size of each element
Both information are known
For example, when the above function is called with
ans = sum(numbers, 6);
in the main(), the address of the first element, &numbers[0], is copied into
the parameter a
The size of each element is determined since the element type (int) is given
(in sunfire, an integer takes up 4 bytes)
18. 1.8 Accessing Array Elements in Function (2/2)
Week8 - 18
Why is it not necessary to
have a value in here to
indicate the “real” size?
A function header with array parameter,
int sum(int a[ ], int size)
With this, the system is able to calculate the effective address of the
required element, say a[2], by the following formula:
Address of a[2] = base address + (2 size of each element)
where base address is the address of the first element
Hence, suppose the base address is 2400, then address of a[2] is
calculated to be 2408.
19 12
5 7 ...
a[0] a[1] a[2] a[3]
19. 2. Multidimensional Arrays (1/2)
In general, an array can have any number of dimensions
Example of a 2-dimensional (2D) array:
Week8 - 19
// array with 3 rows, 5 columns
int a[3][5];
a[0][0] = 2;
a[2][4] = 9;
a[1][0] = a[2][4] + 7;
Arrays are stored in row-major order
a[0][0] … a[0][4] a[1][0] … a[1][4] a[2][0] … a[2][4]
row 0 row 1 row 2
0 1 2 3 4
0
1
2
2
9
16
21. 2.1 Multidimensional Array Initializers
Week8 - 21
// nesting one-dimensional initializers
int a[3][5] = { {4, 2, 1, 0, 0},
{8, 3, 3, 1, 6},
{0, 0 ,0, 0, 0} };
// the first dimension can be unspecified
int b[][5] = { {4, 2, 1, 0, 0},
{8, 3, 3, 1, 6},
{0, 0, 0, 0, 0} };
// initializer with implicit zero values
int d[3][5] = { {4, 2, 1},
{8, 3, 3, 1, 6} };
What happens to
the uninitialized
elements?
22. 2.2 Multidimensional Array: Example
Week8 - 22
#include <stdio.h>
#define N 5 // number of columns in array
int sumArray(int [][N], int); // function prototype
int main(void) {
int foo[][N] = { {3,7,1}, {2,1}, {4,6,2} };
printf("Sum is %dn", sumArray(foo, 3));
printf("Sum is %dn", sumArray(foo, 2));
return 0;
}
// To sum all elements in arr
int sumArray(int arr[][N], int rows) {
int i, j, total = 0;
for (i = 0; i < rows; i++) {
for (j = 0; j < N; j++) {
total += arr[i][j];
}
}
return total;
}
Week8_2DArray.c
Second dimension must be
specified; first dimension is
not required.
23. 2.3 Accessing Array Elements in Function
Week8 - 23
Why second dimension
must be specified, but not
the first dimension?
A function header with 2D array parameter,
function(int a[][5], ...)
To access an element in a 2D array, it must know the number of columns. It needs
not know the number of rows.
For example, given the following two 2D-arrays:
: :
A 3-column 2D array: A 5-column 2D array:
As elements are stored linearly in memory in row-major order, element a[1][0]
would be the 4th
element in the 3-column array, whereas it would be the 6th
element
in the 5-column array.
Hence, to access a[1][0] correctly, we need to provide the number of columns in the
array.
For multi-dimensional arrays, all but the first dimension must be specified in the
array parameter.
24. 2.4 Demo #1: Class Enrolment (1/5)
A class enrolment system can be represented by a 2D array enrol, where
the rows represent the classes, and columns the students. For simplicity,
classes and students are identified by non-negative integers.
A ‘1’ in enrol[c][s] indicates student s is enrolled in class c; a ‘0’ means s is
not enrolled in c.
Assume at most 10 classes and 30 students.
Example of an enrolment system with 3 classes and 8 students:
Week8 - 24
Queries:
Name any class with the most
number of students
Name all students who are enrolled
in all the classes
1 0
1 0
1 0
1 1
0 1 1 1
1 1
1 0
1 0
1 1
0 0 1 0
1
0
2
0 1 2 3 4 5 6 7
25. 2.4 Demo #1: Class Enrolment (2/5)
Inputs:
Number of classes and students
Number of data entries
Each data entry consists of 2 integers s and c indicating that student s is
enrolled in class c.
Sample input:
Week8 - 25
Number of classes and students: 3 8
Number of data entries: 15
Enter 15 entries (student class):
3 1
0 0
0 1
1 2
2 0
2 1
2 2
3 2
7 1
6 0
5 0
4 1
4 0
6 2
6 1
1 0
1 0
1 0
1 1
0 1 1 1
1 1
1 0
1 0
1 1
0 0 1 0
1
0
2
0 1 2 3 4 5 6 7
26. 2.4 Demo #1: Class Enrolment (3/5)
Week8 - 26
#define MAX_CLASSES 10
#define MAX_STUDENTS 30
int main(void) {
int enrol[MAX_CLASSES][MAX_STUDENTS] = { {0} }, numClasses, numStudents;
readInputs(enrol, &numClasses, &numStudents);
return 0;
}
// Read data into array enrol
void readInputs(int enrol[][MAX_STUDENTS],
int *numClassesPtr, int *numStudentsPtr) {
int entries; // number of data entries
int i, class, student;
printf("Number of classes and students: ");
scanf("%d %d", numClassesPtr, numStudentsPtr);
printf("Number of data entries: ");
scanf("%d", &entries);
printf("Enter %d data entries (student class): n", entries);
// Read data into array enrol
for (i = 0; i < entries; i++) {
scanf("%d %d", &student, &class);
enrol[class][student] = 1;
}
}
3 8
15
3 1
0 0
0 1
1 2
2 0
2 1
2 2
3 2
7 1
6 0
5 0
4 1
4 0
6 2
6 1
1
0
2
0 1 2 3 4 5 6 7
1 0 1 0 1 1 1 0
1 0 1 1 1 0 1 1
0 1 1 1 0 0 1 0
27. 2.4 Demo #1: Class Enrolment (4/5)
Week8 - 27
Query 1: Name any class with the most number of students
Row sums
5
6
4
int classWithMostStudents
(int enrol[][MAX_STUDENTS],
int numClasses, int numStudents) {
int classSizes[MAX_CLASSES];
int r, c; // row and column indices
int maxClass, i;
for (r = 0; r < numClasses; r++) {
classSizes[r] = 0;
for (c = 0; c < numStudents; c++)
classSizes[r] += enrol[r][c];
}
// find the one with most students
maxClass = 0; // assume class 0 has most students
for (i = 1; i < numClasses; i++)
if (classSizes[i] > classSizes[maxClass])
maxClass = i;
return maxClass;
}
1
0
2
0 1 2 3 4 5 6 7
1 0 1 0 1 1 1 0
1 0 1 1 1 0 1 1
0 1 1 1 0 0 1 0
28. 2.4 Demo #1: Class Enrolment (5/5)
Week8 - 28
Query 2: Name all students who are enrolled in all classes
// Find students who are enrolled in all classes
void busiestStudents(int enrol[][MAX_STUDENTS],
int numClasses, int numStudents) {
int sum;
int r, c;
printf("Students who take all classes: ");
for (c = 0; c < numStudents; c++) {
sum = 0;
for (r = 0; r < numClasses; r++)
sum += enrol[r][c];
if (sum == numClasses)
printf("%d ", c);
}
printf("n");
}
Column sums
2 1 3 2 2 1 3 1
Refer to Week8_ClassEnrolment.c
for complete program.
1
0
2
0 1 2 3 4 5 6 7
1 0 1 0 1 1 1 0
1 0 1 1 1 0 1 1
0 1 1 1 0 0 1 0
29. 3. Matrices
Week8 - 29
A two-dimensional array where all rows have the same number of
elements is sometimes known as a matrix because it resembles
that mathematical concept.
A matrix A with m rows and n columns, also called an mn (m by n)
matrix, is represented mathematically in the following manner.
a1 1
a1 2
a1 n
a2 1
a2 2
a2 n
am 1
am 2
am n
Note that in implementing the matrix as an array in C, the row and
column indices start at 0 instead of 1.
30. 3.1 Demo #2: Matrix Addition (1/2)
Week8 - 30
To add two matrices, both must have the same size
(same number of rows and columns).
To compute C = A + B, where A, B, C are matrices
ci,j = ai,j + bi,j
Examples:
0
2
1
1
2
2
0
2
0
1
2
0
0
1
2
0
0
1
1
0
1
1
1
0
0
2
1
20
22
11
10
29
25
28
13
15
8
5
6
20
18
7
3
5
14
6
4
9
7
21
10
31. 3.1 Demo #2: Matrix Addition (2/2)
Week8 - 31
// To sum mtxA and mtxB to obtain mtxC
void sumMatrix(float mtxA[][MAX_COL], float mtxB[][MAX_COL],
float mtxC[][MAX_COL], int row_size, int col_size) {
int row, col;
for (row=0; row<row_size; row++)
for (col=0; col<col_size; col++)
mtxC[row][col] = mtxA[row][col] + mtxB[row][col];
}
Week8_matrixOps.c
+ =
10
4
21
6
7
14
9
5
3
6
7
5
18
8
20
15
?
?
?
?
?
?
? ?
13 28
10 11
25
22 20
29
32. n p
matrix
m n
matrix
3.2 Exercise #1: Matrix Multiplication (1/3)
Week8 - 32
To multiply two matrices A and B, the number of columns
in A must be the same as the number of rows in B.
The resulting matrix has same number of rows as A and
number of columns as B.
For example, multiplying a 24 matrix with a 43 matrix
gives a 23 matrix.
= m p
matrix
33. 3.2 Exercise #1: Matrix Multiplication (2/3)
Week8 - 33
To compute C = A B, where A, B, C are matrices
ci,j = (ai,1 b1,j ) + (ai,2 b2,j ) + . . . + (ai,n bn,j )
ci,j is sum of terms produced by multiplying the elements of A’s
row i with B’s column j.
Examples:
1
2
1
1
3
2
0
2
3
1
2
0
0
1
2
0
0
1
1
0
1
1
1
0
0
2
1
Complete the prodMatrix() function in Week8_matrixOps.c
6
13
13
11
17
15
3
1
2
0
3
1
3
2
2
1
2
3
1
2
0
3
2
3
1
2
35. 4. Maze Problem (1/2)
Let’s consider a maze that is represented by a two-
dimensional 6 6 integer array.
The value of each array element is either 0 (representing a
wall) or 1 (representing a cell).
The starting and exit points in the maze are specified by the
cells maze[0][0] and maze[5][5] respectively.
A path is represented by a single-dimensional character array
with four possible element values representing the move
directions: ‘N’ (for north), ‘S’ (for south), ‘E’ (for east), and
‘W’ (for west). Each path is defined with respect to the
starting cell maze[0][0].
Week8 - 35
36. 4. Maze Problem (2/2)
Example of a 6 6 maze
Week8 - 36
0 1 2 3 4 5
0
1
2
3
4
5
Start
Exit
Cell
Wall
37. 4. Exercise #2: Valid Path
A path in a maze is defined to be valid if the path is within
the maze and does not knock against any wall.
Examples:
Valid path: ‘E’, ‘E’, ‘S’, ‘N’, ‘E’, ‘E’, ‘S’
Invalid path: ‘S’, ‘S’, ‘W’
Invalid path: ‘S’, ‘S’, ‘S’, ‘E’
Write a function
int isValid (int maze[][6], char path[])
that takes in a 6 6 maze and a path with at most 10 characters. It
returns 1 if path is valid in maze, or returns 0 otherwise.
This is a take-home exercise.
An incomplete program Week8_IsValid.c is given. It handles string input
which is not covered yet.
Week8 - 37
0 1 2 3 4 5
0
1
2
3
4
5