Laboratory Exercises For Computer Science 153

Searching Algorithms

Searching Algorithms

Background: One of the most common applications of computing involves locating an item which has been stored within a data set. For example, the Registrar's Office might be interested in determining transcript information of a given student or checking if a student is registered for a specified class. This laboratory exercise outlines several approaches for searching a data set for a given item. These approaches are applied both in the context of a simple game and for general arrays.

Example: The Hi-Lo Game Consider the following simple number game between two parties, A and B. Initially, A chooses an integer between 1 and 100 (inclusive). B then tries to guess this number. In this guessing process, B makes a guess and then A responds by saying either that the guess is "correct", or that the guess is "too high", or that the guess is "too low". This process continues until B makes a correct guess. (In playing the game, B might have some incentive to try to determine the correct number quickly, but the game itself does not require this.)

Class AsNumber.java provides a simple class which simulates A's role in the above game, and program HiLo.java uses AsNumber.java to allow a user to play B's part in this game.

  1. Review both AsNumber.java and HiLo.java to see how they work.

  2. Copy both AsNumber.java and HiLo.java, compile them, and run HiLo to see how they work.

Now, consider B's strategy in the game. Several approaches are possible, including the following:

  1. B might guess numbers randomly until choosing the correct one.

  2. B might guess numbers in sequence 1, 2, 3, ..., 100 (or 100, 99, 98, ..., 2, 1), stopping once the correct integer is found. (Computer scientists call this approach a sequential search.)

  3. B might guess a number in the middle (e.g., 50 or 51). On the basis of the answer (``correct'', ``too low'', ``too high''), B could then infer that some numbers need not be tried at all, and B could reduce the range of numbers possible for [1..100] to [1..50] or [51..100] (depending upon A's response). As a second guess, B could try the middle of this new interval, and again the interval of possible values could be cut in half on the basis of A's response. This process of guessing a middle value and cutting the interval of possible candidates in half could continue until the number is found. (This approach is called a binary search.)

Each of these approaches naturally involves a loop. For approach a, each guess should be made without regard for the past. For approaches b or c, subsequent steps should depend upon feedback from A in earlier rounds. Thus, for approaches b and c, we must keep some information as we work through a loop.

  1. Modify the original version of HiLo.java to simulate approach a above. As the program proceeds, it should print out the successive numbers that it guesses.

    Reminder: Use the operator == to test if two numbers are the same and != to check if they are different.
    (Do not use =, as this is the assignment operator!)

  2. Modify the previous version of HiLo.java, following the random guessing approach as in the previous step, but printing out only the number of guesses made and the final, correct answer.

  3. Add a second guessing loop to HiLo.java from the previous step to implement approach b above. Thus, in this version of the program, A's guess will first be found using random guessing and then will be determined using a sequential search. While the program may print the number of guesses for random guessing, the program should print each successive guess it makes for the sequential search.

    In writing your code, you may want to use local variables to store any relevant information.

  4. Writing a correct binary search can be somewhat tricky.

    As a first step, write out (in English) what information should be kept from one iteration of the loop to the next. Explain what inferences might be made from this kept information, and describe (again, in English) how this information should be updated when the next feedback from A is obtained.

  5. Now add a third guessing loop, implementing your outline in the previous step of this lab. As in the previous steps, print out the successive guesses to verify the program works correctly.

  6. Modify the previous HiLo.java program, so that it prints only the number of guesses used in each approach and the final value. (Of course, if each of your loops works correctly, the final value printed for each approach should be the same.)

  7. Expand HiLo.java from the previous step to play the game for 10 different number selections by A. What can you say about the number of guesses by B for each algorithm? Which algorithm(s) is (are) most efficient? Briefly justify your answer.

B's strategies for identifying a number between 1 and 100 may be applied to many other situations as well. One common problems in computing, for example, involves determining whether or not specific information has been stored previously. A second problem involves locating a specific piece of information and retrieving it.

  1. Write a new program searchArray which reads 10 integers into an array. (Define a variable to give the size of the array, so the program may be changed easily in the future to accommodate searches of different sized arrays.)

    1. Adapt the sequential search code above to determine whether a given value is stored in the array. In your approach, would it matter if the data in the array were sorted? Why or why not?

    2. Adapt the binary search to determine whether a sorted array contains a given value?

  2. Modify your program, so that it contains two arrays -- an array of names (strings) and an array of telephone numbers (also stored as strings). If these arrays are called name and number, respectively, the person whose name is name[i] would have number[i]. Use your search algorithm to find a person in the name array, and print out the corresponding telephone number. A simple directory shell program for this problem is found at DirectoryShell.java.

    Note: You will need to use String methods to compare strings; the relevant methods are equals and compareTo. For String variables str1 and str2, the syntax for comparing strings follows:


This document is available on the World Wide Web as

http://www.math.grin.edu/~walker/courses/153.sp00/lab-searching.html

created April 16, 1997
last revised April 23, 2000