Array algorithms for searching and displaying/retrieving element values
Lesson content
- About algorithms for searching and displaying/retrieving array elements
- Searching and displaying all array elements (in normal or reverse order)
- Searching and displaying only certain array elements (in normal or reverse order)
- Searching and retrieving specific values from the array (first or last occurrence)
- Searching and counting specific values in the array
- Most common errors
About algorithms for searching and displaying/retrieving array elements
One of the simplest tasks when working with arrays is displaying (printing) the elements of an array on the screen. In the chapter on arrays, the corresponding algorithm was presented without much introduction or explanation.
But what if we need to do this output a bit differently — say, in reverse order, or print only some of the elements? Or, more generally, what if we need to perform some kind of search (selection), and then print only the found elements, retrieve or count them, or return their position in the array?
This lesson covers some basic algorithms for searching and displaying/retrieving elements of an array. These algorithms are characterized by the following:
- They do not change the values of the array elements or their order (“read-only” approach).
- They may include some form of searching (e.g., finding values greater than, less than, etc.), but it’s not required.
- The result is printing (display) to the screen, or counting, or an indicator of whether a specific value exists in the array.
Searching and displaying all array elements (in normal or reverse order)
The algorithm for printing all array elements in normal order (from the first element to the last) boils down to traversing the entire array using a FOR or FOR-EACH loop and printing one element per iteration. To print from the first to the last element in order, the loop counter starts at 0 and increments by 1 until it reaches the array length minus one.
Printing all elements in reverse order also uses a FOR loop in almost the same way — printing one element per iteration. The difference is that the loop counter starts at the index of the last element (length - 1) and decreases by 1 each time until it reaches 0. A FOR-EACH loop cannot be used here because it does not support iterating over an array in reverse order.
Example 1
Create a class named TestPrinting that has:
- An attribute charArray that should use quick array initialization with the letters A, B, C, D, and E.
- A method print that prints all elements of the array from the first to the last. This method should use a FOR loop.
- A method printA that also prints all elements from the first to the last, but uses a FOR-EACH loop.
- A method printReversed that prints all array elements from the last to the first.
- A main method that creates an instance of the TestPrinting class and calls all three printing methods.
1 class TestPrinting {
2
3 char[] charArray = {'A', 'B', 'C', 'D', 'E'};
4
5 void print(){
6 for (int i = 0; i < charArray.length; i++)
7 System.out.println(charArray[i]);
8 }
9
10 void printA(){
11 for (char letter : charArray)
12 System.out.println(letter);
13 }
14
15 void printReversed(){
16 for (int i = charArray.length-1; i >= 0; i--)
17 System.out.println(charArray[i]);
18 }
19
20 public static void main(String[] args) {
21 TestPrinting tp = new TestPrinting();
22
23 tp.print();
24
25 tp.printA();
26
27 tp.printReversed();
28 }
29 }
The charArray attribute is quickly initialized with the starting values A, B, C, D, E, and you can see two different methods for printing using two variants of the same algorithm: print and printA.
The print method uses a regular FOR loop where the loop counter follows the array index values — from 0 to charArray.length - 1.
The printA method uses a FOR-EACH loop for the same purpose, where the helper variable letter is of type char.A FOR-EACH loop is perfectly suitable here because the array values are not modified, and we’re iterating through the entire array in normal order.
The printReversed method uses a FOR loop where the loop counter starts from the last index (charArray.length - 1) and decreases (i—) until it reaches the index of the first element (0). This way, in the first iteration, the last array element is printed, then the second-to-last, and so on. In this case, it is not possible to create an alternative version using a FOR-EACH loop, because that loop can only go from the beginning to the end of the array.
What happens when you use a counter (element count) in a class that contains an array?
The algorithms are very similar, but instead of looping to the array’s full length (length - 1), you loop only up to the current number of used elements (counter - 1). For this reason, a FOR-EACH loop cannot be used, only a standard FOR loop. The FOR-EACH loop always iterates through the entire array capacity, not up to the current counter value.
Example 2
Create a class TestPrinting2 that has:
- An attribute charArray which is immediately initialized with a capacity of 10.
- An attribute counter that represents the number of letters entered into the array. The initial value is zero.
- A method insert that inserts a new letter into the array. The array should be filled sequentially from the beginning. If there is no more space in the array, print the message “ERROR” to the screen.
- A method print that prints all elements of the array from the first to the last entered.
- A method printReversed that prints all elements of the array from the last entered to the first.
- A main method that creates an object of the TestPrinting2 class, inserts the letters A, B, C, D, E into the array, and calls both print methods.
1 class TestPrinting2 {
2
3 char[] charArray = new char[10];
4 int counter = 0;
5
6 void insert(char newLetter){
7 if (counter < charArray.length){
8 charArray[counter] = newLetter;
9 counter++;
10 }
11 else System.out.println("ERROR");
12 }
13
14 void print(){
15 for (int i = 0; i < counter; i++)
16 System.out.println(charArray[i]);
17 }
18
19 void printReversed(){
20 for (int i = counter -1; i >= 0; i--)
21 System.out.println(charArray[i]);
22 }
23
24 public static void main(String[] args) {
25 TestPrinting2 tp = new TestPrinting2();
26
27 tp.insert('A');
28 tp.insert('B');
29 tp.insert('C');
30 tp.insert('D');
31 tp.insert('E');
32
33 tp.print();
34
35 tp.printReversed();
36 }
37 }
Searching and displaying only certain array elements (in normal or reverse order)
What happens if, when printing the elements of an array, we don’t need to print all of them?
For example, what if we only want to print every second element, or only the even numbers in the array?
In such cases, the algorithms for printing from the previous examples are slightly modified — either by changing how the loop counter progresses, or by adding a nested IF statement inside the FOR loop to check whether the current element meets the required condition.
Example 3
Create a class TestSearchPrinting that has:
- An attribute numberArray that is quickly initialized with the numbers: 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, and 20.
- A method printEverySecond that prints every second element of the array from first to last. Use a modified increment for the loop counter.
- A method printEverySecondA that also prints every second element from first to last but uses a nested IF statement to achieve this.
- A method printEverySecondReversed that prints every second element from last to first, using a modified decrement of the loop counter.
- A method printEverySecondReversedA that does the same, using a nested IF statement.
- A method printDivisibleByThree that prints only the elements divisible by 3. This method should use a FOR loop.
- A method printDivisibleByThreeA that also prints only the elements divisible by 3, but uses a FOR-EACH loop.
- A main method where an object of TestSearchPrinting is created and all print methods are called.
1 class TestSearchPrinting {
2
3 int[] numberArray = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
4
5 void printEverySecond(){
6 for (int i = 0; i < numberArray.length; i = i + 2)
7 System.out.println(numberArray[i]);
8 }
9
10 void printEverySecondA(){
11 for (int i = 0; i < numberArray.length; i++)
12 if (i % 2 == 0)
13 System.out.println(numberArray[i]);
14 }
15
16 void printEverySecondReversed(){
17 for (int i = numberArray.length-1; i >= 0; i = i - 2)
18 System.out.println(numberArray[i]);
19 }
20
21 void printEverySecondReversedA(){
22 for (int i = numberArray.length-1; i >= 0; i--)
23 if (i % 2 == 0)
24 System.out.println(numberArray[i]);
25 }
26
27 void printDivisibleByThree(){
28 for (int i = 0; i < numberArray.length; i++)
29 if (numberArray[i] % 3 == 0)
30 System.out.println(numberArray[i]);
31 }
32
33 void printDivisibleByThreeA(){
34 for (int number : numberArray)
35 if (number % 3 == 0)
36 System.out.println(number);
37 }
38
39 public static void main(String[] args) {
40 TestSearchPrinting tsp = new TestSearchPrinting();
41
42 tsp.printEverySecond();
43
44 tsp.printEverySecondA();
45
46 tsp.printEverySecondReversed();
47
48 tsp.printEverySecondReversedA();
49
50 tsp.printDivisibleByThree();
51
52 tsp.printDivisibleByThreeA();
53 }
54 }
In the method printEverySecond, printing every second element is achieved by increasing the loop counter by 2 at the end of each iteration (i = i + 2) instead of the usual increment by 1. As a result, the loop counter will take values 0, 2, 4, 6, etc., so every second element will be printed. Note: The total number of iterations is halved because one element is skipped in each cycle.
The alternative approach is shown in the method printEverySecondA, where a nested IF checks whether the loop counter is an even number. This causes the element to be printed only if the loop counter is divisible by 2, i.e., for values 0, 2, 4, 6, etc. Unlike the previous method, the number of iterations here equals the number of array elements.
In the methods printEverySecondReversed and printEverySecondReversedA, similar logic is applied, but the printing goes from the last element to the first.
- In the first method, the loop counter is decreased by 2 on each iteration.
- In the second, a nested IF checks whether the counter is even.
The method printDivisibleByThree contains an algorithm that prints only those elements divisible by 3. This is done using a nested IF inside a FOR loop that checks if the current element is divisible by 3.
The method printDivisibleByThreeA uses a similar algorithm, but written using a FOR-EACH loop with a nested IF statement.
If the class has a counter (e.g., for tracking how many elements are actually inserted into the array), the algorithms would be very similar — but they would not iterate up to the full array length (length - 1), but only up to the counter value (counter - 1). Because of this, it would not be possible to use a FOR-EACH loop in such cases — only a standard FOR loop would work.
Example 4
Create a class TestSearchPrinting2 that has:
- An attribute numberArray which is immediately initialized with a capacity of 20.
- An attribute counter that represents how many numbers have been entered into the array. The initial value is zero.
- A method printEverySecondA that also prints every second element from first to last but uses a nested IF statement to achieve this.
- A method printEverySecondReversed that prints every second element from last to first, using a modified decrement of the loop counter.
- A method printEverySecondReversedA that does the same, using a nested IF statement.
- A method printDivisibleByThree that prints only the elements divisible by 3. This method should use a FOR loop.
- A method printDivisibleByThreeA that also prints only the elements divisible by 3, but uses a FOR-EACH loop.
- A main method in which an object of the TestSearchPrinting2 class is created, numbers 10 through 20 are inserted into the array, and all the print methods are called.
1 class TestSearchPrinting2 {
2
3 int[] numberArray = new int[20];
4 int counter = 0;
5
6 void insert (int newNumber){
7 if (counter < numberArray.length){
8 numberArray[counter] = newNumber;
9 counter++;
10 }
11 else System.out.println("ERROR");
12 }
13
14 void printEverySecond(){
15 for (int i = 0; i < counter; i = i + 2)
16 System.out.println(numberArray[i]);
17 }
18
19 void printEverySecondA(){
20 for (int i = 0; i < counter; i++)
21 if (i % 2 == 0)
22 System.out.println(numberArray[i]);
23 }
24
25 void printEverySecondReversed(){
26 for (int i = counter -1; i >= 0; i = i - 2)
27 System.out.println(numberArray[i]);
28 }
29
30 void printEverySecondReversedA(){
31 for (int i = counter -1; i >= 0; i--)
32 if (i % 2 == 0)
33 System.out.println(numberArray[i]);
34 }
35
36 void printDivisibleByThree(){
37 for (int i = 0; i < counter; i++)
38 if (numberArray[i] % 3 == 0)
39 System.out.println(numberArray[i]);
40 }
41
42 public static void main(String[] args) {
43 TestSearchPrinting2 tsp = new TestSearchPrinting2();
44
45 tsp.insert(10);
46 tsp.insert(11);
47 tsp.insert(12);
48 tsp.insert(13);
49 tsp.insert(14);
50 tsp.insert(15);
51 tsp.insert(16);
52 tsp.insert(17);
53 tsp.insert(18);
54 tsp.insert(19);
55 tsp.insert(20);
56
57 tsp.printEverySecond();
58
59 tsp.printEverySecondA();
60
61 tsp.printEverySecondReversed();
62
63 tsp.printEverySecondReversedA();
64
65 tsp.printDivisibleByThree();
66 }
67 }
Searching and retrieving specific values from the array (first or last occurrence)
When it is necessary to check whether a certain value exists in an array — i.e., whether any element of the array holds that value — we’re talking about search and retrieve algorithms (commonly known in English as “search and retrieve” or just “search”).
These algorithms are typically implemented using a FOR or FOR-EACH loop, along with a nested IF statement to check whether the current element matches the target value.
If the target value is found, the search usually stops immediately, as continuing would be unnecessary.
The typical return value of such algorithms is either:
- A boolean indicator showing whether the array contains the desired value (true or false) or
- The position (index) of the array element that contains the value being searched for.
Example 5
Create a class TestSearchRetrieve that has:
- An attribute charArray that is quickly initialized to contain the letters B, A, N, A, N, A.
- A method contains that takes a character as a parameter and checks if any element in the array contains that character. If found, the method returns true; otherwise, it returns false. Use a FOR loop.
- A method containsA that also checks for a character, using a FOR-EACH loop instead.
- A method findFirst that returns the index of the first occurrence of the given character in the array (starting from the beginning). If not found, it returns -1.
- A method findLast that returns the index of the last occurrence of the character in the array (also indexed from the beginning). If not found, it returns -1.
- A main method where an object of TestSearchRetrieve is created and all the methods are called.
1 class TestSearchRetrieve {
2
3 char[] charArray = {'B', 'A', 'N', 'A', 'N', 'A'};
4
5 boolean contains(char letter){
6 for (int i = 0; i < charArray.length; i++)
7 if (charArray[i] == letter)
8 return true;
9
10 return false;
11 }
12
13 boolean containsA(char letter){
14 for(char arrayLetter : charArray)
15 if (arrayLetter == letter)
16 return true;
17
18 return false;
19 }
20
21 int findFirst(char letter){
22 for (int i = 0; i < charArray.length; i++)
23 if (charArray[i] == letter)
24 return i;
25
26 return -1;
27 }
28
29 int findLast(char letter){
30 for (int i = charArray.length-1; i >= 0; i--)
31 if (charArray[i] == letter)
32 return i;
33
34 return -1;
35 }
36
37 public static void main(String[] args) {
38 TestSearchRetrieve tsr = new TestSearchRetrieve();
39
40 System.out.println("The array contains the letter N: " + tsr.contains('N'));
41 System.out.println("The array contains the letter S: " + tsr.containsA('S'));
42
43 System.out.println("Position of the first letter A in the array: " + tsr.findFirst('A'));
44 System.out.println("Position of the last letter A in the array: " + tsr.findLast('A'));
45 }
46 }
In the contains method, the most common type of search is implemented: whether the array contains a certain value or not. The FOR loop goes through the array indices, and the IF statement checks each element to see if it matches the desired character.
If the character is found, the method returns true, and both the FOR loop and the method itself immediately terminate with the return statement. This is appropriate because there’s no point in continuing the search once the value has been found.
However, if the loop finishes and no match is found, the method reaches the final return statement (“return false;”) and returns false.
A common mistake is to place the final return statement (“return false;”) in the else branch of the IF statement, like this:
1 boolean contains(char letter){
2 for (int i = 0; i < charArray.length; i++)
3 if (charArray[i] == letter)
4 return true;
5 else
6 return false;
7 }
This should not be done. It results in a logic error because if the first element doesn’t match, the method immediately returns false without checking the rest of the array. It also leads to a syntax issue if the array is empty, since neither branch may return a value. This kind of problem is discussed in more detail in the lesson on FOR loops.
The containsA method has the same logic as the contains method, but is implemented using a FOR-EACH loop.
The findFirst method works similarly to contains. The FOR loop checks each index of the array with an IF statement. However, instead of returning true, it returns the index of the first element that matches the desired character. This is done with “return i;”. The search stops immediately once a match is found.
Why is this the first element? Because the search starts from the beginning of the array (index 0), and it stops when the first match is found. If the entire array is scanned and no match is found, the method returns -1.
- A FOR-EACH loop is not suitable here because we need the index of the found element, which the FOR-EACH loop does not provide.*
The method findLast is almost identical to findFirst, except it searches the array in reverse order. Finding the last occurrence of a character (from the beginning of the array) is equivalent to finding the first occurrence while searching from the end of the array. Therefore, by iterating from length - 1 to 0, you return the first match found in that reverse loop — which is the last occurrence in the array overall.
As in previous examples, if you’re using a counter (to track how many elements have been added to the array), these algorithms must use a FOR loop that iterates up to counter - 1, not the array’s full capacity (length - 1).
Searching and counting specific values in the array
A common type of problem involves counting values rather than simply finding them.
For example:
- Counting how many students received a grade of 5.
- Counting how many patients have a body temperature of 37.0°C or higher.
In both cases, all relevant data is stored in an array, and we simply need to count the number of elements that meet a given condition.
From an algorithmic perspective, the first step is to introduce a helper counter to keep track of how many desired values have been found.
- This counter is initialized to zero.
- Then a FOR or FOR-EACH loop is used.
- Inside the loop, an IF statement checks each element.
- Every time the condition is satisfied, the helper counter is incremented by one.
Example 6
Create a class ControlPanel that has:
An attribute switches, which is an array where each element represents a switch on the control panel. If a switch is on, the corresponding element in the array is true; if it is off, the value is false.
A constructor that takes the total number of switches on the control panel as a parameter and initializes the switches array to that capacity.
A method turnOnSwitch that receives a switch number (from 1 to the total number of switches) and “turns on” the corresponding switch by setting its value to true. If the switch number is out of bounds, the method prints “ERROR” on the screen.
A method turnOffSwitch that receives a switch number (from 1 to total number of switches) and “turns off” the corresponding switch by setting its value to false. If the switch number is out of bounds, it also prints “ERROR” on the screen.
A method countOnSwitches that counts and returns the total number of switches that are turned in the on position (from the switches array). Use a FOR loop.
A method countOnSwitchesA that does the same, but using a FOR-EACH loop.
A method countOffSwitches that counts and returns the total number of switches that are turned in the off position (from the switches array) using a FOR loop.
A method countOffSwitchesA that does the same, using a FOR-EACH loop.
1 class ControlPanel {
2
3 boolean[] switches;
4
5 ControlPanel(int numberOfSwitches){
6 switches = new boolean[numberOfSwitches];
7 }
8
9 void turnOnSwitch(int switchNumber){
10 if (switchNumber >= 1 && switchNumber <= switches.length)
11 switches[switchNumber -1] = true;
12 else
13 System.out.print("ERROR ");
14 }
15
16 void turnOffSwitch(int switchNumber){
17 if (switchNumber >= 1 && switchNumber <= switches.length)
18 switches[switchNumber -1] = false;
19 else
20 System.out.print("ERROR ");
21 }
22
23 int countOnSwitches(){
24 int onSwitches = 0;
25
26 for(int i = 0; i< switches.length; i++)
27 if (switches[i] == true)
28 onSwitches++;
29
30 return onSwitches;
31 }
32
33 int countOnSwitchesA(){
34 int onSwitches = 0;
35
36 for(boolean sw : switches)
37 if (sw == true)
38 onSwitches++;
39
40 return onSwitches;
41 }
42
43 int countOffSwitches(){
44 int offSwitches = 0;
45
46 for(int i = 0; i< switches.length; i++)
47 if (switches[i] == false)
48 offSwitches++;
49
50 return offSwitches;
51 }
52
53 int countOffSwitchesA(){
54 int offSwitches = 0;
55
56 for(boolean sw : switches)
57 if (sw == false)
58 offSwitches++;
59
60 return offSwitches;
61 }
62 }
Create a class TestControlPanel. In its main method:
- Create an object of the class ControlPanel with four switches.
- Turn on the second and fourth switches.
- Then turn off the fourth switch.
- After that, print the total number of on and off switches.
1 class TestControlPanel {
2
3 public static void main(String[] args) {
4 ControlPanel cp = new ControlPanel(4);
5
6 cp.turnOnSwitch(2);
7 cp.turnOnSwitch(4);
8
9 cp.turnOffSwitch(4);
10
11 System.out.println("Total number of ON switches: " +
12 cp.countOnSwitches());
13
14 System.out.println("Total number of OFF switches: " +
15 cp.countOffSwitches());
16
17 System.out.println("Total number of ON switches (FOR-EACH): " +
18 cp.countOnSwitchesA());
19
20 System.out.println("Total number of OFF switches (FOR-EACH): " +
21 cp.countOffSwitchesA());
22 }
23 }
The constructor initializes the array to the given number of switches. The turnOnSwitch and turnOffSwitch methods set the corresponding array element to true or false. This was already covered in detail in the lesson on arrays, so it won’t be explained here again.
In the method countOnSwitches, a counter variable onSwitches is used to track how many switches are on. A FOR loop iterates through the array, and a nested IF statement checks whether the current element is true. If it is, the counter is incremented. At the end, the method returns the counter’s value.
In the method countOnSwitchesA, the same thing is done using a FOR-EACH loop. A helper variable sw is used to get the current value from the array, and then an IF statement checks if it’s true.
The methods countOffSwitches and countOffSwitchesA contain almost identical algorithms as the previous two methods. The only difference is that they are looking for off switches (i.e., elements with the value false). Everything else stays the same:
- FOR or FOR-EACH loop
- Nested IF condition
- A helper counter to track the number of off switches
Naturally, if a counter is used in the class to track the number of entered elements in the array, these counting algorithms must only use a FOR loop, with the loop index going from 0 to counter - 1 (and not from 0 to length - 1).
Most common errors
Some of the most common syntax errors related to the use of algorithms for searching and displaying/retrieving array elements are:
- Placing both the “YES” and “NO” branches of a nested IF statement (inside a FOR or FOR-EACH loop that iterates over the array) in methods that return something. First, this causes a syntax error because the method won’t return anything if the array is empty. Second, the loop will certainly break during the first iteration:
1 boolean contains(char letter){
2 for (int i = 0; i < charArray.length; i++)
3 if (charArray[i] == letter)
4 return true;
5 else
6 return false;
7 }
Instead, the correct version is:
1 boolean contains(char letter){
2 for (int i = 0; i < charArray.length; i++)
3 if (charArray[i] == letter)
4 return true;
5
6 return false;
7 }
Other common mistakes that are not syntax errors, but affect the program’s behavior, include:
- Using a FOR-EACH loop when the class contains a helper counter of elements (i.e., actually entered values). In this case, the entire array is looped through by mistake (including empty spots), and not just the actually entered values, for example:
1 char[] charArray = new char[10];
2 int counter = 0;
3
4 void print(){
5 for (char letter: charArray)
6 System.out.println(letter);
7 }
Instead, correctly (use only a FOR loop from 0 to counter - 1):
1 char[] charArray = new char[10];
2 int counter = 0;
3
4 void print(){
5 for (int i = 0; i < counter; i++)
6 System.out.println(charArray[i]);
7 }
- Using a FOR loop when the class contains a helper counter of elements (i.e., actually entered values) but looping through the entire array (from 0 to length - 1) instead of just up to the value of the counter (from 0 to counter - 1), for example:
1 char[] charArray = new char[10];
2 int counter = 0;
3
4 void print(){
5 for (int i = 0; i < charArray.length; i++)
6 System.out.println(charArray[i]);
7 }
Instead, correctly (a FOR loop from 0 to counter - 1):
1 char[] charArray = new char[10];
2 int counter = 0;
3
4 void print(){
5 for (int i = 0; i < counter; i++)
6 System.out.println(charArray[i]);
7 }