标签:
练习1.16
这道题题目特别长,说的无非就是要用一个不变量记录中间结果,然后写出对数步数内的通过迭代来计算幂的函数,当然了还要用到题目中括号内的那个关系。下面就直接上代码了:
(define (fast-expt b n)
(fast-expt-iter 1 b n))
(define (fast-expt-iter a b n)
(cond ((= n 0) a)
((even? n) (fast-expt-iter a
(square b)
(/ n 2)))
((odd? n) (fast-expt-iter (* a b)
b
(- n 1)))))
写完代码无一例外的就是测试了:
(fast-expt 2 30)
;Value: 1073741824
(fast-expt 0.123 4)
;Value: .000228886641
练习1.17
这道题中有2个需要我们自己先写出来的函数double和halve,当然了,这都非常容易实现:
(define (double x)
(+ x x))
(define (halve x)
(/ x 2))
题目中要求我们设计一个类似于fast-expt的求乘积的过程,并且只用对数的步数。
(define (* x y)
(cond ((= y 0) 0)
((even? y) (double (* x (halve y))))
((odd? y) (+ x (* x (- y 1))))))
我们继续来测试一下:
(* 2 10)
;Value: 20
(* 3 60)
;Value: 180
练习1.8
和前两题一样,依旧是只能用对数步数。而且这个迭代过程要基于加、加倍和折半运算。这一个习题要用到前面的函数,因此最好的做法是,每次都将写好的代码保存起来。
(load “Test1.18.scm”)
这行代码可以用来加载代码。而保存可以用C-X,C-W。
以下是该题的代码,这次我们写成块结构:
(define (* x y)
(define (*-iter x y product)
(cond ((= y 0) product)
((even? y) (*-iter (double x)
(halve y)
product))
((odd? y) (*-iter x
(- y 1)
(+ x product)))))
(*-iter x y 0))
依旧还是来测试一番:
(* 18 3)
;Value: 54
(* 0.123456789 987654321)
;Value: 121932631.11263525
练习1.19
题目中说道斐波那契数中将变换T的n次方应用于对偶(1,0)而产生出来,而现在将T看作T(pq)中p=0和q=1的特俗情况。因此对于对偶(a,b)来说,a—bq+a(p+q),b—bp+aq。而对于T(pq)的平方也就是(T(pq))^2,就像之前的a中往b乘以q和往a乘以(p+q),现在依旧是相当于a中往bp+aq乘以q(bp+aq为上一次迭代中的”b”),往(bq+a(p+q))中乘以(p+q),同样的变换也发生在b中。依次对于T(pq)的平方来说,a—b(2pq+q*q)+a(p*p+q*q+2*p*q+q*q),b—b(p*p+q*q)+a(2pq+q*q)。
而再次通过对比我们发现p’=p^2+q^2并且q’=2pq+q^2。
所以当N为偶数时,我们又可以通过应用变换T(p’q’)来减少计算T^N的一半计算量,因此在这种情况下就可以写出对数步数的斐波那契函数了。代码如下:
(define (fib n)
(define (fib-iter a b p q n)
(cond ((= n 0) b)
((even? n) (fib-iter a b (+ (square p) (square q))
(+ (* 2 p q) (square q)) (/ n 2)))
((odd? n) (fib-iter (+ (* b q) (* a q) (* a p))
(+ (* b p) (* a q)) p q (- n 1)))))
(fib-iter 1 0 0 1 n))
再来一次测试:
(fib 0)
;Value: 0
(fib 7)
;Value: 13
标签:
原文地址:http://www.cnblogs.com/NoMasp/p/4275777.html