Accumulator Arrays
A Programming Pattern |

Prof. David Bernstein |

Computer Science Department |

bernstdh@jmu.edu |

Motivation

- Recall:
- We sometimes need to "keep track of" something across iterations using an accumulator

- A Related Problem:
- We need to "keep track of" multiple things across iterations

- Solutions:
- Sometimes it is best to use multiple different accumulators
- Sometimes it is best to use an array of accumulators

An Example

- The Setting:
- A school that assign numeric grades on a scale of 0 to 100

- The Need:
- A summary report that shows the number of students that were in each centile (i.e., the 100s, the 90s, the 80s, etc...).

Review

Given what you know, you might proceed as follows:

int ones, tens, twentys, thirtys, fortys, fiftys, sixtys, seventys, eightys, ninetys, hundreds; ones = tens = twentys = thirtys = fortys = fiftys = sixtys = seventys = eightys = ninetys = hundreds = 0;

int n = Array.getLength(data); for (int i = 0; i < n; i++) { if (data[i] < 10) ones++; else if (data[i] < 20) tens++; else if (data[i] < 30) twentys++; else if (data[i] < 40) thirtys++; else if (data[i] < 50) fortys++; else if (data[i] < 60) fiftys++; else if (data[i] < 70) sixtys++; else if (data[i] < 80) seventys++; else if (data[i] < 90) eightys++; else if (data[i] < 100) ninetys++; else hundreds++; }

Shortcomings

- All of the variables must be declared and initialized individually
- The nested
`if`

statement that is used to update the appropriate accumulator is both awkward and error-prone - Since methods in Java can only return a single entity, you could not write a re-usable method to perform these calculations

Thinking About this Example

- One Observation:
- In situations like this (i.e., when you have multiple "related" values) it is better to use an array than to use individual variables

- Another Observation:
- Truncation can be used to determine the centiles (i.e., the indexes)

The Pattern

- Declare and initialize an array to hold the number of accumulators needed
- Create an algorithm for identifying the index of the particular accumulator that needs to be updated during a particular iteration
- Write a loop that calculates the index and updates the appropriate accumulator

Examples

/** * Create a frequency histogram by centile for an array * of numeric grades (in the range [0, 100]). * * @param data The array of grades * @return The frequencies */ public static int[] gradeHistogram(int[] data) { int centile, n; int[] count = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; n = Array.getLength(data); for (int i = 0; i < n; i++) { centile = data[i] / 10; count[centile] += 1; } return count; }

Examples (cont.)

/** * Count the number of odd and even elements * in an array. Element 0 contains the number of even values, * element 1 contains the number of odd values. * * @param data The data * @return An array containing the counts */ public static int[] oddsAndEvens(int[] data) { int[] count = {0, 0}; int n = Array.getLength(data); for (int i = 0; i < n; i++) { count[data[i] % 2] += 1; } return count; }

Examples (cont.)

/** * Count the number of negative, zero, and positive elements * in an array. Element 0 contains the number of negative values, * element 1 contains the number of 0s, and element 2 contains the * number of positive values. * * @param data The data * @return An array containing the counts */ public static int[] signs(int[] data) { int[] count = {0, 0, 0}; int n = Array.getLength(data); for (int i = 0; i < n; i++) { if (data[i] < 0) count[0]++; else if (data[i] == 0) count[1]++; else count[2]++; } return count; }