Paul Ngugi

Posted on

# Case Study on Single-Dimensional Arrays

## Case Study: Analyzing Numbers

The problem is to write a program that finds the number of items above the average of all items. The problem is to read 100 numbers, get the average of these numbers, and find the number of the items greater than the average. To be flexible for handling any number of input, we will let the user enter the number of input, rather than fixing it to 100. Below is the solution.

The program prompts the user to enter the array size (line 8) and creates an array with the specified size (line 9). The program reads the input, stores numbers into the array (line 14), adds each number to sum in line 14, and obtains the average (line 18). It then compares each number in the array with the average to count the number of values above the average (lines 20-23).

## Case Study: Deck of Cards

The problem is to create a program that will randomly select four cards from a deck of cards. Say you want to write a program that will pick four cards at random from a deck of 52 cards. All the cards can be represented using an array named deck, filled with initial values 0 to 51, as follows:

```int[] deck = new int[52]; // Initialize cards for (int i = 0; i < deck.length; i++) deck[i] = i;```

Card numbers 0 to 12, 13 to 25, 26 to 38, and 39 to 51 represent 13 Spades, 13 Hearts, 13 Diamonds, and 13 Clubs, respectively, as shown in below in (a). cardNumber / 13 determines the suit of the card and cardNumber % 13 determines the rank of the card, as shown in below in (b). After shuffling the array deck, pick the first four cards from deck. The program displays the cards from these four card numbers.

(a)

(b)

Below is the code:

The program creates an array suits for four suits (line 7) and an array ranks for 13 cards in a suit (lines 8). Each element in these arrays is a string.

The program initializes deck with values 0 to 51 in lines 11–12. The deck value 0 represents the card Ace of Spades, 1 represents the card 2 of Spades, 13 represents the card Ace of Hearts, and 14 represents the card 2 of Hearts.

Lines 15–21 randomly shuffle the deck. After a deck is shuffled, deck[i] contains an arbitrary value. deck[i] / 13 is 0, 1, 2, or 3, which determines the suit (line 25). deck[i] % 13 is a value between 0 and 12, which determines the rank (line 26). If the suits array is not defined, you would have to determine the suit using a lengthy multi-way if-else statement as follows:

```if (deck[i] / 13 == 0) System.out.print("suit is Spades"); else if (deck[i] / 13 == 1) System.out.print("suit is Hearts"); else if (deck[i] / 13 == 2) System.out.print("suit is Diamonds"); else System.out.print("suit is Clubs");```

With suits = {"Spades", "Hearts", "Diamonds", "Clubs"} created in an array, suits[deck / 13] gives the suit for the deck. Using arrays greatly simplifies the solution for this program.

## Case Study: Counting the Occurrences of Each Letter

This section presents a program to count the occurrences of each letter in an array of characters. The program given below does the following:

1. Generates 100 lowercase letters randomly and assigns them to an array of characters, as shown in the image below a. You can obtain a random letter by using the getRandomLowerCaseLetter() method in the RandomCharacter class.
2. Count the occurrences of each letter in the array. To do so, create an array, say counts, of 26 int values, each of which counts the occurrences of a letter, as shown in the image below b. That is, counts[0] counts the number of a’s, counts[1] counts the number of b’s, and so on.

``````package demo;

public class CountLettersInArray {

public static void main(String[] args) {
// Declare and create an array
char[] chars = createArray();

// Display the array
System.out.println("The lowercase letters are:");
displayArray(chars);

// Count the occurrences of each letter
int[] counts = countLetters(chars);

// Display counts
System.out.println();
System.out.println("The occurrences of each letter are:");
displayCounts(counts);
}

/** Create an array of characters */
public static char[] createArray() {
// Declare an array of characters and create it
char[] chars = new char[100];

// Create lowercase letters randomly and assign them to the array
for(int i = 0; i < chars.length; i++)
chars[i] = RandomCharacter.getRandomLowerCaseLetter();

// Return the array
return chars;
}

/** Display the array of characters */
public static void displayArray(char[] chars) {
// Display the characters in the array 20 on each line
for(int i = 0; i < chars.length; i ++) {
if((i + 1) % 20 == 0)
System.out.println(chars[i]);
else
System.out.print(chars[i] + " ");
}
}

/** Count the occurrences of each letter */
public static int[] countLetters(char[] chars) {
// Declare and create an array of 26 int
int[] counts = new int[26];

// For each lowercase letter in the array, count it
for(int i = 0; i < chars.length; i++)
counts[chars[i] - 'a']++;

return counts;
}

/** Display counts */
public static void displayCounts(int[] counts) {
for(int i = 0; i < counts.length; i++) {
if((i + 1) % 10 == 0)
System.out.println(counts[i] + " " + (char)(i + 'a'));
else
System.out.print(counts[i] + " " + (char)(i + 'a') + " ");
}
}

}

``````

```The lowercase letters are: e y l s r i b k j v j h a b z n w b t v s c c k r d w a m p w v u n q a m p l o a z g d e g f i n d x m z o u l o z j v h w i w n t g x w c d o t x h y v z y z q e a m f w p g u q t r e n n w f c r f The occurrences of each letter are: 5 a 3 b 4 c 4 d 4 e 4 f 4 g 3 h 3 i 3 j 2 k 3 l 4 m 6 n 4 o 3 p 3 q 4 r 2 s 4 t 3 u 5 v 8 w 3 x 3 y 6 z```

The createArray method (lines 23–33) generates an array of 100 random lowercase letters. Line 7 invokes the method and assigns the array to chars. What would be wrong if you rewrote the code as follows?

```char[] chars = new char[100]; chars = createArray();```

You would be creating two arrays. The first line would create an array by using new char[100]. The second line would create an array by invoking createArray() and assign the reference of the array to chars. The array created in the first line would be garbage because it is no longer referenced, and as mentioned earlier Java automatically collects garbage behind the scenes. Your program would compile and run correctly, but it would create an array unnecessarily.

Invoking getRandomLowerCaseLetter() (line 29) returns a random lowercase letter. This method is defined in the RandomCharacter class.

The countLetters method (lines 47–56) returns an array of 26 int values, each of which stores the number of occurrences of a letter. The method processes each letter in the array and increases its count by one. A brute-force approach to count the occurrences of each letter might be as follows:

```for (int i = 0; i < chars.length; i++) if (chars[i] == 'a') counts[0]++; else if (chars[i] == 'b') counts[1]++; ...```

But a better solution is given in lines 52–53.

```for (int i = 0; i < chars.length; i++) counts[chars[i] - 'a']++;```

If the letter (chars[i]) is a, the corresponding count is counts['a' - 'a'] (i.e., counts[0]). If the letter is b, the corresponding count is counts['b' - 'a'] (i.e., counts[1]), since the Unicode of b is one more than that of a. If the letter is z, the corresponding count is counts['z' - 'a'] (i.e., counts[25]), since the Unicode of z is 25 more than that of a.

Above image shows the call stack and heap during and after executing createArray.