练习1.18-练习1.22

1.练习1.18

(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

p=p2+q2

q=q2+2pq

完整的函数如下:

(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相似。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页