您的位置:首页 > 理论基础

SICP-《计算机程序的构造和解释》之习题分析与收获——练习1.29

2014-12-06 17:21 162 查看
前面给出了sum函数的定义:

(define (sum term a next b)
    (if (> a b)
        0
        (+ (term a)
           (sum term (next a) next b))))
//功能为求f(a)到f(b)的和。

这里我们要求的辛普森公式里的每一项(a)为两部分构成:乘法因子和y。所有我们要把他抽象为另一个函数:

(define (term k)
(* (factor k) (y k)))

这里的乘法因子是关于k奇数为4偶数为2,当k为0或n的时候就是1.则有:

(define (factor k)
(cond ((or(= k 0)(= k n)) 1)
 
((odd? k) 4)
 
(else 2)))
 
根题yk=f(a+kh),直接写出来为:

(define (y k)
f((+ a (* k h))))
//这里的f使用的是最外层函数的参数函数

于是我们就可以利用sum函数和我们定义的函数解决右括号里的求和问题,这里发现还少了一个next:

(define (next a)
(+ a 1))

于是调用方式为: sum term 0 n 

于是我们开始构造外层函数--(我的顺序是不是有问题~):

(load "p38-sum.scm")//sum是题目给出的算法,前面有介绍
(define (simpson f a b n)   
//先嵌入函数
//顺序为先变量,再底层函数,再上层函数  (这里用的是现在流行语言的一些定义名称)
(define h (/ (- b a) n))
(define (factor k)
(cond ((or(= k 0)(= k n)) 1)
 
((odd? k) 4)
 
(else 2)))
(define (y k)
f((+ a (* k h))))
(define (term k)
(* (factor k) (y k)))
(define (next a)
(+ a 1))
//以下为函数主体
(if (not (even? n))          
   //这里不用(odd? n)是为了保证它是一个偶数从而限制其他可能的输出情况
 
 (error "n can't be odd"))   //error放前面提示这是一个错误
(*(/ h 3)            
          //分开放方便查看
(sum term 0 next n))))      //最后一个)对应第一个define前面的(

至此应该已经通过高阶函数抽象把这个辛普森这个式子用程序实现了。这个例子没有前面的递归那么思维逻辑有一定要求,但是它主要让我们练习深入了这种抽象过程的思维过程好比sum是一种求和的公共模式,这里就存在一种很实用的抽象,于是我们有了sum这个函数,而当我们使用这个函数模板时我们需要根据他的参数把自己的数据和过程抽象出来。刚开始题目提供了一个函数f,我就直接把这个f当做sun的term参数去套,然后发现他前面还有乘法因子,然后我试着用4f(a+kh)去给参数term赋值,但这个参数只是一个过程,所以,怎么办。然后我就想到了把4f(a+kh)这种复杂的东西抽象为F(k),于是一切都很好控制了。也许,现代的编程语言也是把这一切过程都抽象为函数吧,所谓的黑箱科学吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SICP 函数抽象 Lisp