`
阿尔萨斯
  • 浏览: 4192932 次
社区版块
存档分类
最新评论

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))





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics