码迷,mamicode.com
首页 > 其他好文 > 详细

【SICP练习】6 练习1.16-1.19

时间:2015-02-05 20:23:27      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

练习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

【SICP练习】6 练习1.16-1.19

标签:

原文地址:http://www.cnblogs.com/NoMasp/p/4275777.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!