SICP 练习 (1.31)解题总结
SICP 习题 (1.31)解题总结
SICP 习题1.31开始拔高我们的抽象能力,向更高的高度进发,以更好地理解高阶函数。
习题1.31是基于1.30的。
在习题1.30中我们定义了累加的过程sum,其实我们可以发现,这种累积操作是可以做更高的抽象的。
在做更高的抽象之前让我们看看使用乘法做累积的代码是什么样的,这就是题目要求我们完成的第一个任务,做函数值的乘积。
定义出来的过程如下:
(define (product term a next b) (if (> a b) 1 (* (term a) (product term (next a) next b))))
可以发现,除了其中的+号变成了*号,初始值由0变成了1,这个过程和sum几乎是一样的。
另外,题目还要求我们实现迭代版的函数值乘积,定义出来的过程如下:
(define (product-iter term a next b ) (define (iter a result) (if (> a b) result (iter (next a) (* (term a) result)))) (iter a 1))
同样,迭代版的乘积累积过程和迭代版的累加过程几乎是一样的,除了*号代替+号,1代替0.
不知道在哪里听说过,如果我们在重复输入大量相同的代码,肯定是哪里出问题了。
我们应该是把乘法的累积和加法的累积做成一个抽象的叫“累积”的过程,然后将“乘法”或者是“加法”作为参数传进去。
当然,这一切是在高阶函数成立的条件下才可以做到的。
这就是后面的习题1.32要做的事情,更多的我们在下一题再讨论。
回到习题1.31,题目还要求我们根据公式“pie/4=(2/3)*(4/3)*(4/5)*(6/5)*(6/7)*(8/7)…”求出pie的近似值。
其实我们可以将以上公式写成下面这样:
pie/4=f(1)*f(2)*f(3)*f(4)*f(5)*f(6)…f(k)
其中,如果k是偶数,f(k)=(K+2)/(k+1)
如果k是奇数,f(k)=(k+1)/(k+2)
使用Scheme代码定义的这个f(k)为:
(define (for-pie k) (if (even? k) (/ (+ k 2) (+ k 1)) (/ (+ k 1) (+ k 2))))
这样我们可以利用上面的product过程来完成习题,定义的过程如下:
(define (generate-pie n) (* (product for-pie 1 next-integer n) 4.0))
其中next-integer用于生成下一个整数,过程如下:
(define (next-integer a) (+ a 1))