Recursive Process V.S. Iterative Process
Recursive process
The substitution model of a recursive process reveals a shape of expansion followed by constraction. The expansion occurs as the process builds up a chain of defered operations. The contraction occurs as the operations are actually performed.
Iterative process
An iterative process is one whose state can be summarized by a fixed number of state variables, together with a fixed rule that describes how the state variables should be updated as the process moves from state to state and an (optional) end test that specifies the conditions under which the process should terminate.
In the iterative case, the program variables provide a complete description of the state of the process at any point, while in the recursive case, there is some additional "hidden" information, maintained by the interpreter and not contained in the program variables.
In contrasting iteration and recursion, we must be careful not to confuse the notion of a recursive process with the notion of a recursive procedure. When we describe a procedure as recursive, we are referring to the syntactic fact that the procedure definition refers (either directly or indirectly) to the procedure itself. But when we describe a process as following a pattern that is, say, linearly recursive, we are speaking about how the process evolves, not about the syntax of how a procedure is written. It may seem disturbing that we refer to a recursive procedure as generating an iterative process.
Lame's Theorem
If Euclid's Algorithm requires k steps to compute the GCD of some pair, then the smaller number in the pair must be greater than or equal to the kth Fibonacci number.
Fermat's Little Theorem
If n is a prime number and a is any positive integer less than n, then a raised to the nth power is congruent to a modulo n.
Exercises
1.9 Answer: The first process is recursive and the second one is iterative.
1.10 Answer: from the definition of (A x y), we have:
(A 1 10) = A(0 (A 1 9)) = 2 * (A 1 9) = ... = 2^9 * (A 1 1) = 2^10
(A 2 4) = 65536
(A 3 3) = 65536
(f n) computes 2n
(g n) computes 2^n
(h n) computes 2^2^2... (n times)
1.11 Answer: This is similar with the example of computing Fibonacci number.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1.12
1 2 3 4 5 6 |
|
1.15 Answer:
a. from the the procedure definition, suppose p will be called t times, we have:
a / (3^t) <= 0.1, which leads to:
log(10a) <= t, so t = ceiling (log(10a)) = 5, (the base of the log is 3)
b. both the space and number of steps depend on how many times p is called, so it's O(t) = O(log(a)).
1.16
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1.17
1 2 3 4 5 6 7 |
|
1.18
1 2 3 4 5 6 7 8 9 10 11 |
|
1.19
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
1.21
1 2 3 4 5 6 7 8 |
|
1.25 Answer:
Since Scheme has built-in support for arbitrary precision arithmetic, the procedure will produce the same result as the original expmod, however, it will be very inefficient since the huge number arithmetic will take much longer time than the numbers can be represented by a single computer word.
The original expmod used the successive squaring, the numbers to be processed will never be larger than m^2.
1.26 Answer:
With the calling of square, the original problem can be reduced to a sub problem with half of the size at each of the step when even? test is true. So T(n) = T(n/2) = O(logn)
However, if the explicit multiplication used instead, the recursive call of expmod will be evaluated twice, it not only just compute the sub problems two time, it is actually a tree recursion like the first solution for computing fibnacci sequence, so the number of expmod calls grow exponentially, which conclues that T(n) = O(2^n * logn) = O(n)
1.27
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
1.28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|