此題與1.32、1.33是一個(gè)系列題,沒(méi)什么難度,只不過(guò)把sum的加改成乘就可以了,遞歸與迭代版本相應(yīng)修改即可:
;(define (product term a next b)
; (if (> a b)
; 1
; (* (term a) (product term (next a) next b))))
(define (product-iter term a next b result)
(if (> a b)
result
(product-iter term (next a) next b (* result (term a)))))
分號(hào)注釋的是遞歸版本。利用product過(guò)程生成一個(gè)計(jì)算pi的過(guò)程,也是很簡(jiǎn)單,通過(guò)觀察公式的規(guī)律即可得出:
(define (product term a next b)
(product-iter term a next b 1))
(define (inc x) (+ x 2))
(define (pi-term n)(/ (* (- n 1) (+ n 1)) (* n n)))
(define (product-pi a b)
(product pi-term a inc b))
測(cè)試一下:
> (* 4 (product-pi 3 1000))
3.1431638424191978569077933
再來(lái)看習(xí)題1.32,如果說(shuō)sum和product過(guò)程是一定程度的抽象,將對(duì)累積項(xiàng)和下一項(xiàng)的處理抽象為過(guò)程作為參數(shù)提取出來(lái),那么這個(gè)題目要求將累積的操作也作為參數(shù)提取出來(lái),是更高層次的抽象,同樣也難不倒我們:
(define (accumulate combiner null-value term a next b)
(if (> a b)
null-value
(combiner (term a) (accumulate combiner null-value term (next a) next b))))
OK,其中combiner是進(jìn)行累積的操作,而null-value值基本值?,F(xiàn)在改寫(xiě)sum和product過(guò)程,對(duì)于sum過(guò)程來(lái)說(shuō),累積的操作就是加法,而基本值當(dāng)然是0了:
(define (sum term a next b)
(accumulate + 0 term a next b))
而對(duì)于product,累積操作是乘法,而基本值是1,因此:
(define (product term a next b)
(accumulate * 1 term a next b))
測(cè)試一下過(guò)去寫(xiě)的那些測(cè)試程序,比如生成pi的過(guò)程,可以驗(yàn)證一切正常!
上面的accumulate過(guò)程是遞歸版本,對(duì)應(yīng)的迭代版本也很容易改寫(xiě)了:
(define (accumulate-iter combiner term a next b result)
(if (> a b)
result
(accumulate-iter combiner term (next a) next b (combiner result (term a)))))
(define (accumulate combiner null-value term a next b)
(accumulate-iter combiner term a next b null-value))
再看習(xí)題1.33,在accumulate的基礎(chǔ)上多增加一個(gè)filter的參數(shù)(也是一個(gè)過(guò)程,用于判斷項(xiàng)是否符合要求),在accumulate的基礎(chǔ)上稍微修改下,在每次累積之前進(jìn)行判斷即可:
(define (filtered-accumulate combiner null-value term a next b filter)
(cond ((> a b) null-value)
((filter a) (combiner (term a) (filtered-accumulate combiner null-value term (next a) next b filter)))
(else (filtered-accumulate combiner null-value term (next a) next b filter))))
比如,求a到b中的所有素?cái)?shù)之和的過(guò)程可以寫(xiě)為(利用以前寫(xiě)的prime?過(guò)程來(lái)判斷素?cái)?shù)):
(define (sum-primes a b)
(filtered-accumulate + 0 identity a inc b prime?))
測(cè)試一下:
> (sum-primes 2 4)
5
> (sum-primes 2 7)
17
> (sum-primes 2 11)
28
> (sum-primes 2 100)
1060