练习1.18-练习1.22

版权声明:本文为博主原创文章,转载请注明出处,谢谢!

版权声明:本文为博主原创文章,转载请注明出处:http://blog.jerkybible.com/2014/01/08/2014-01-08-练习1.18-练习1.22/

访问原文「练习1.18-练习1.22

1.练习1.18

1
2
3
4
5
6
7
(define (*-iter a b n)
(cond ((= n 0) a)
((even? n) (*-iter a (double b) (halve n)))
(else (*-iter (+ a b) b (- n 1)))))
(define (* b n)
(*-iter 0 b n))

Lisp真是强大啊,连 *-iter这种函数名也可以使用!!!
2.练习1.19

1
p=p2+q2
1
q=q2+2pq

完整的函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(define (next-p p q)
(+ (square p) (square q)))
(define (next-q p q)
(+ (square q) (* 2 (* p q))))
(define (fib-iter a b p q count)
(cond ((= 0 count) b)
((even? count) (fib-iter a
b
(next-p p q)
(next-q p q)
(/ count 2)))
(else (fib-iter (+ (* b q) (* a q) (* a p))
(+ (* b p) (* a q))
p
q
(- count 1)))))

3.练习1.20

应用序4次,第一次算,但是gcd( 2 0)不算,if判断后就直接返回a,下面不会执行;
正则序18次,
正则代换后,则第n层的a b两个参数对应的remainder的次数分别为a(n), b(n),
则: a(n) = b(n-1);b(n)=a(n-1)+b(n-1)+1;a(0)=0,b(0)=0
总共5层,由于每层的if判断进行了计算,再加上最后一层的a是计算了的,所以最后的结果是:b(0)+b(1)+b(2)+b(3)+b(4)+a(4)=18
按照我的理解:
这道题使用正则序展开的时候会先展开gcd,展开的函数中会有多个remiander函数;使用应用序展开时,会先计算remainder,然后才会展开gcd。
看了很多别人的答案,对于正则序的展开并不是很清楚,我一开始认为也是5次,后来发现不对,我现在的想法是,在if的时候求值,在其他地方正常展开。
4.练习1.21
199,1999,7
5.练习1.22
这道题中,我将(runtime)函数,改为(real-time-clock);
计算结果如下:
1000的时间消耗为1;
10000的时间消耗为2;
100000的时间消耗为3;
1000000的时间消耗为8;
10000000的时间消耗为24。
可一看到,在1000-100000之间的时间的增长阶小于根10,而从100000到10000000之间的时间增长阶与根10相似。

Jerky Lu wechat
欢迎加入微信公众号