Functions Involving Loops


Accumulation

You have seen how a loop can accumulate an answer. For example, you can compute the factorial function using a loop in Cinnameg, as follows.

  Define
    factorial(n: Integer): Integer by

    factorial(n) = r |
      Let r = 1.
      Let k = 2.
      While k <= n do
        Relet r = r * k.
        Relet k = k + 1.
      %While
  %Define
Let's write the factorial function in Java. Since factorials can get large, type long seems appropriate. Instead of saying which variable will be the answer, you add a return statement at the end.
  public static long factorial(long n)
  {
    long r = 1;
    long k = 2;
    while(k <= n)
    {
      r = r * k;
      k = k + 1;
    }
    return r;
  }

Notice the similarities between the two definitions above, one written in Cinnameg and the other in Java. The idea is the same, and there is a close correspondence between parts. Remember that a Java function needs a return statement.


Functions that search

Another common use of loops is to search for something. For example, you can test whether a number is prime by searching for a factor of it. Here is a definition of isPrime in Cinnameg, as derived previously.

  Define 
    isPrime(n: Integer): Boolean by

    isPrime(n) = r |
      Let k = 2.
      While k < n and n `mod` k =/= 0 do
        Relet k = k + 1.
      %While
      Let r = (k == n).
  %Define
Here is the same thing converted to Java.
  public static boolean isPrime(int n)
  {
    int k = 2;
    while(k < n && n % k != 0)
    {
      k = k + 1;
    }
    return k == n;
  }

In Java, a return statement ends the function immediately, no matter where it occurs. For example, you can include a return statement inside a loop, and doing it ends the loop immediately. That is useful in doing searches, which should stop as soon as they find what they are looking for. Here is another way to write the isPrime function. Notice that the test to see whether k is a factor of n has been moved into the loop body. As soon as you find a factor of n, you know that n is not prime.

  public static boolean isPrime(int n)
  {
    int k = 2;
    while(k < n)
    {
      if(n % k == 0) return false;
      k = k + 1;
    }
    return true;
  }


Problems

  1. [solve] Function power(x,n) has the following heading.

      public static int power(int x, int n)
    
    Write a definition of power so that it returns xn. Assume that n is positive. Use a loop to accumulate the power.

  2. [solve] Using a loop, define function num7s(n) in Java, which takes an integer n and returns the number of 7s in the usual (base 10) representation of n. For example, num7s(2770) = 2 and num7s(99) = 0. Assume that the argument and answer both have type int.

    (Hint. Successively divide the number by 10. Remember that k % 10 is the rightmost digit of k, and k/10 gives you the number that you get by removing the rightmost digit from k.)

  3. [solve] Using a loop, define function any7s(n), which takes an integer n and returns true if the usual (base 10) representation of n contains a 7. For example, any7s(274) = true, but any7s(99) = false. Assume that the argument has type int. The answer has type boolean.

    (Hint. Successively divide the number by 10. You are searching for a number whose rightmost digit is a 7. The search is exhausted when the number is 0. For example, when n is 3791, you look at 3791, 379, 37, and stop, because the rightmost digit of 37 is 7. When n is 999, you look at 999, 99, 9, 0, and stop because the search has reached 0. So only keep searching when you current number is not 0 and does not have rightmost digit 7.)


Summary

The body of a function can contain any kinds of statements, including loops. Use loops in cases where functions have to do repetitive tasks, such as accumulating an answer or searching for something.


Review

A Java function has only one body, which is always a compound statement. Use statement

  return E;
to say that the function's answer is the value of expression E.