借用练习题1.22和1.20中判断质数和欧几里得算法的过程,然后编写带过滤器的过程filtered-accumulate。
#lang racket
(define (square x) (* x x))
(define (inc n) (+ n 1))
(define (identity x) x)
(define (add a b) (+ a b))
(define (mult a b) (* a b))
//判断质数部分
(define(smallest-divisor n)
(find-divisor n 2))
(define(find-divisor n test-divisor)
(cond((>(square test-divisor) n ) n)
((divides? test-divisor n) test-divisor)
(else(find-divisor n (+ test-divisor 1)))))
(define(divides? a b)
(=(remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
//带过滤器的accumulate方法
(define (filtered-accumulate filter conbiner null-value term a next b)
(if (> a b)
null-value
(if (filter a) (conbiner (term a)
(filtered-accumulate filter conbiner null-value term (next a) next b))
(filtered-accumulate filter conbiner null-value term (next a) next b))))
(define (sum-prime a b)
(filtered-accumulate prime? add 0 identity a inc b))
//判断两个数是不是互素,最大公约数是1
(define (gcd a b)
(if (= b 0)
a
(gcd b (remainder a b))))
(define (mult-coprime n)
(define (coprime? a)
(if (= 1 (gcd a n)) #t #f))
(filtered-accumulate coprime? mult 1 identity 1 inc n))
(sum-prime 1 10)
(mult-coprime 7)
这里我们抽取的判断互质的过滤器需要用到两个参数,所以将它定义到了mult-coprime过程内部,以保证能采用我们的通用过程filtered-accumulate,因为它的filter只有一个参数。
最终运行结果:
18
720