14. Loop Algorithms 2: Search Algorithms


Search algorithms

A search algorithm searches through a sequence of values looking for a value that has a particular property. There are usually two possible outcomes.

  1. A value with the desired property is found. In that case, there is no need to search further.

  2. The entire sequence is searched without finding a suitable value.

Notice that in one case, where a sought value is found, the search algorithm can stop the search early, and does not need to look at the entire sequence. In the other case, the algorithm needs to look at the entire sequence.


Examples

Suppose you want nextPrime(n) to return the smallest prime number that is greater than n. Notice that there will always exist such a prime number (assuming no integer overflow) so, in this case, there is no need to worry about what to do if no sought for value is found.

  int nextPrime(int n)
  {
    for(int i = n+1; !isPrime(i); i++) {}
    return i;
  }
Notice that, if i is prime, the search algorithm can stop immediately. But if i is not prime, another value for i needs to be tried.

Now let's try an algorithm that can fail to find what it is searching for. Member(x, A, n) returns true if one of the values A[0], A[1], ... A[n−1] is equal to x. It is required that n ≥ 0.

  bool member(const int x, const int A[], const int n)
  {
    for(int i = 0; i < n; i++)
    {
      if(A[i] == x)
      {
        return true;
      }
    }
    return false;
  }
Notice that member can return true early, but it can only return false if has gone through the entire loop.

Now let's look at a problem that, at first glance, might not look like a search problem at all. allPositive(A, n) returns true if every one of A[0], A[1], ..., A[n−1] is a positive number. This is a search problem because it is searching for a number that is not positive. If it finds one, then the answer is obviously false, and the algorithm can stop without looking at the entire array.

  bool allPositive(const int A[], const int n)
  {
    for(int i = 0; i < n; i++)
    {
      if(A[i] <= 0)
      {
        return false;
      }
    }
    return true;
  }


Search algorithm requirement

In your programming assignment submissions, you are required to use a search algorithm to solve a search problem.

The following is an example of what not to do. Suppose that you want to know whether the first n numbers in array A are all positive. One way to do that is to count the number of positive values and ask it that count is equal to n. Here is an implementation of that idea.

  bool allPositive(int A[], int n)
  {
    count = 0;
    for(int i = 0; i < n; i++)
    {
      if(A[i] > 0)
      {
        count++;
      }
    }
    return (count == n);
  }

That gets the right answer, but it needs to look at every number, no matter what. If you think of it as a search problem, allPositive(A, n) is responsible for searching for a negative number. As soon as it sees a negative number or 0, the answer is obvious. You only need to look at all n numbers if they are all positive. Here is a definition of allPositive as a search algorithm.

  bool allPositive(int A[], int n)
  {
    count = 0;
    for(int i = 0; i < n; i++)
    {
      if(A[i] <= 0)
      {
        return false
      }
    }
    return true;
  }

Using a scan algorithm to solve a search problem will lose 1-3 points.


Exercises

  1. Write a definition of function firstPositive(A, n), which returns the first positive number in list A[0], ..., A[n-1], or returns 0 if none of those numbers is positive. Use a loop.

    Assume that n has type int and that A is an array of ints. firstPositive(A, 0) should return 0.

    Answer

  2. Write a definition of function allPrime(A, n), which returns true if all of A[0], ..., A[n-1] are prime numbers, and returns false otherwise. Use a loop. Assume that A is an array of ints and use function isPrime(n) to tell if n is prime. Answer