SICP 习题 1.33将之前抽象的accumulate过程继续往上拔,要求我们定义一个带过滤器的accumulate过程,在这个过程中加多一个参数,这个参数是另一个过程,用来做过滤器。
比如我们调用
(filtered-accumulate 奇数?+ 0 my-self 1 next-int 100)
就是列出1到100的数,对每个数调用(奇数? n),如果结果为真就将这个数加入到累积结果中,如果结果位假就忽略这个数,不将它加入到累积结果中。
明白了这个要求后写代码就比较简单了,我写的代码如下:
(define (filtered-accumulate filter combiner null-value term a next b) (if (> a b) null-value (if (filter a) (combiner (term a) (filtered-accumulate filter combiner null-value term (next a) next b)) (combiner null-value (filtered-accumulate filter combiner null-value term (next a) next b)) )))
其中最关键的就是对(filter a)的调用,如果(filter a)为真,就进行累积,如果(filter a)为假,就使用null-value进行累积。按我们的定义,对null-value进行累积相当于是没有累积。
同时,我惯性地实现了迭代版的filtered-accumulate:
(define (filtered-accumulate-iter filter combiner null-value term a next b ) (define (iter a result) (if (> a b) result (if (filter a) (iter (next a) (combiner (term a) result)) (iter (next a) (combiner null-value result))))) (iter a null-value))
后面题目要求我们通过filtered-accumulate求a到b的素数和,调用方式如下:
(filtered-accumulate prime? + 0 my-self a next-int b)
最后题目还要求我们通过filtered-accumulate求所有小于n的与n互素的正整数的乘积,定义的过程如下:
(define (gcd-eq-1 n) (filtered-accumulate (lambda (i) (= (gcd i n) 1)) * 1 my-self 1 next-int (- n 1)) )
这里事实上作者给我们出了个难题,在我们的filtered-accumulate中,会对a到b之间的数逐个调用(filter i),以判断i是否满足过滤条件,但是这里的过滤条件比较特殊,同时需要i和n才能确定是否满足过滤条件。那么应该如何实现呢?其实这个在接着的下一节就要讲到,就是lambda函数。
有关lambda函数我们后面继续讨论,大家可以先看看上面的调用过程,看看能不能看出点感觉来。
SICP 习题 (1.33)解题总结,布布扣,bubuko.com
原文:http://blog.csdn.net/keyboardota/article/details/19261363