这一节,我们来做一个map,筛选出以下数对里和为素数的数对
c/r | 1 | 2 | 3 | 4 |
---|---|---|---|---|
1 | (1 1) | |||
2 | (2 1) | (2 2) | ||
3 | (3 1) | (3 3) | ||
4 | (4 1) | (4 2) | (4 3) | (4 4) |
这种生成素数序对的过程,可以抽象成以下两个大过程:
构建序对—-筛选序对
函数意义上来讲,就是筛选构建好的序对
构建序对:
构建这些序列,在C系语言中,用for或者while循环是很容易实现的:
for(i = 1; i <=4 ; i++)
for(j = 1; j <= i; j++)
cons(i, j);
但是不用循环控制语句,直接用函数怎样生成这些序列呢?
> (define (make_cons n)
(accumulate append
'()
(map (lambda (i)
(map (lambda (j) (list i j))
(enumerate_interval 1 i)))
(enumerate_interval 1 n))))
生成序列(list 1 2 3 4 … n)
对于每个元素映射生成子表 1 => (list 1)
对于生成的的序列再映射生成子表 ((list 1 1))
对于每个元素映射生成子表 2 => (list 1 2)
对于生成的的序列再映射生成子表((list 2 1) (list 2 2))
对于每个元素映射生成子表 3 => (list 1 2 3)
对于生成的的序列再映射生成子表((list 3 1) (list 3 2) (list 3 3))
…
这是两级嵌套映射,当然还可以有三级嵌套映射、四级嵌套映射……
将其独立出来成一个过程为:
(define (flatmap proc sequence)
(accumulate append '() (map proc sequence)))
筛选序对:
检查是否为素数的函数:
> (define (prime? n)
(define (iter i)
(cond ((= i n) #t)
((= (mod n i) 0) #f)
(else
(iter (+ i 1)))))
(iter 2))
(也可以用更高效的费玛小定律判定是否为素数)
检查序对和是否为素数的函数:
> (define (prime_pair? pair)
(if (prime? (+ (car pair) (cadr pair))) #t #f))
生成的结果为一个三元组(x y (x + y)),生成三元组的函数:
> (define (make_pair pair)
(list (car pair) (cdr pair) (+ (car pair) (cdr pair))))
最终Scheme代码:
> (define (prime_sum_pairs n)
(map make_pair
(filter prime_sum?
(flatmap
(lambda (i)
(map (lambda (j) (list i j))
(enumerate_interval 1 (- i 1)))) ;构造从1到i-1的序列即可
(enumerate_interval 1 n)))))