Searching an Array

  1. A common programming task is to search an array for a given target value. If the target value is found, we want to know the index of the element holding that target value. We will write a function to perform this task.

  2. The simplest way is to use the sequential search algorithm: the function inspects each element in the array from the first to the last element (or vice versa) to see if it matches the target value. Once a match is found, the function returns the index of the element whose value matches the target value.

  3. If no match is found after inspecting all the elements of the array, then the function returns -1. Since a -1 cannot be the index of an array element, this value indicates that a match is not found.

  4. Our textbook has the following implementation:

    //Searches a partially filled array of nonnegative integers.
    #include <iostream>
    using namespace std;

    const int DECLARED_SIZE = 20;

    void fill_array(int a[ ], int size, int& number_used);
    //Precondition: size is the declared size of the array a.
    //Postcondition: number_used is the number of values stored in a.
    //a[0] through a[number_used-1] have been filled with
    //nonnegative integers read from the keyboard.

    int search(const int a[ ], int number_used, int target);
    //Precondition: number_used is <= the declared size of a.
    //Also, a[0] through a[number_used -1] have values.
    //Returns the first index such that a[index] == target,
    //provided there is such an index, otherwise returns -1.

    int main( )
    {
        int arr[DECLARED_SIZE], list_size, target;

        fill_array(arr, DECLARED_SIZE, list_size);

        char ans;
        int result;
        do
        {
            cout << "Enter a number to search for: ";
            cin >> target;

            result = search(arr, list_size, target);
            if (result == -1)
                    cout << target << " is not on the list.\n";
            else
                    cout << target << " is stored in array position "
                              << result << endl
                              << "(Remember: The first position is 0.)\n";

            cout << "Search again?(y/n followed by return): ";
            cin >> ans;
        } while ((ans != 'n') && (ans != 'N'));

        cout << "End of program.\n";
        return 0;
    }

    //Uses iostream:
    void fill_array(int a[ ], int size, int& number_used)
    {
        cout << "Enter up to " << size
                    << " nonnegative whole numbers.\n"
                    << "Mark the end of the list"
                    << " with a negative number.\n";
        int next, index = 0;
        cin >> next;
        while ((next >= 0) && (index < size))
        {
            a[index] = next;
            index++;
            cin >> next;
        }

        number_used = index;
    }

    int search(const int a[ ], int number_used, int target)
    {
        int index = 0;
        bool found = false;
        while ((!found) && (index < number_used))
            if (target == a[index])
                found = true;
            else
                index++;

        if (found)
            return index;
        else
            return -1;
        }

  5. The above implementation of the function search is inefficient and clumsy. Essentially the same implementation is found in other textbooks, such as the one by Friedman and Koffman. Can you see a better way to write it?

  6. The best implementation of the search function that I have received from the students is shown below:

    // Replace the body of the search function by the following:

    for (int n = number_used - 1; n > -2; n--)
        if ( n == -1 || a[n] == target) return n;

    (I changed the variable names to match those used here.) Note that it is quite a bit shorter than the one found in books. It does not require the use of a Boolean variable, and has one less if statement. Also note that no matter how hard one tries, one statement is always needed for the search function since it must return an integer. I suggest that the order of the two conditions inside the if statement should be reversed to improve (very very slightly) the efficiency.

  7. My own version of the search function is to replace the body by the following:

    while ((a[number_used] != target) && (number_used-- > 0));
    return number_used;

    Note that the while-loop has no body. This version is interesting because an additional index n is not needed, and the case where a match is not found is treated more efficiently here.

  8. These alternate ways of coding the search function are interesting, however one must always be sure that the meaning of the codes are not very obscure to other programmers.

  9. This example shows that we should not only try to answer the questions, but to question the answers as well.