SICP 全笔记

Exercise 1.26. Louis Reasoner is having great difficulty doing exercise 1.24. His fast-prime? test seems to run more slowly than his prime? test. Louis calls his friend Eva Lu Ator over to help. When they examine Louis’s code, they find that he has rewritten the expmod procedure to use an explicit multiplication, rather than calling square:

(define (expmod base exp m)
  (cond ((= exp 0) 1)
        ((even? exp)
         (remainder (* (expmod base (/ exp 2) m)
                       (expmod base (/ exp 2) m))
                    m))
        (else
         (remainder (* base (expmod base (- exp 1) m))
                    m))))

‘‘I don’t see what difference that could make,‘’ says Louis. ‘‘I do.‘’ says Eva. ‘‘By writing the procedure like that, you have transformed the (log n) process into a (n) process.‘’ Explain.

原来的过程中,square 部分是:

(remainder (square (expmod base (/ exp 2) m))
           m)

现在被写成了

(remainder (* (expmod base (/ exp 2) m)
              (expmod base (/ exp 2) m))
           m)

也就是说,对于一个 exp = n 的操作,以前在递归的的时候能够每次对 n 进行 n / 2 的操作,现在需要 $\frac{n}{2}\times{2}$ 次,与线性递归的次数一样,所以是 $\theta(n)$