范围
程序: 嵌套映射结构 ;permutation
嵌套映射
主要介绍一种方法,将高级语言中多重循环的语句用嵌套映射的计算方式表达。
问题:给定自然数 n ,找出不同的序对 (i, j)
, 满足:$ 1 ≤ j ≤ i ≤ n $, 且 $ i + j $ 是素数。假定 n 为 6,则结果应该如下:
i | j | i+j |
---|---|---|
2 | 1 | 3 |
3 | 2 | 5 |
4 | 1 | 5 |
4 | 3 | 7 |
5 | 2 | 7 |
6 | 1 | 7 |
6 | 5 | 11 |
最自然的解法是;生成所有小于等于 n 的自然数的全序对,进行过滤,选出和为素数的序对。对通过过滤的序对,产生一个三元组(i, j, i + j)
。
在高级语言中会这样子产生序对:对于 $ i ≤ n $,枚举 $ j ≤ i $。
1 | for(i = 1; i<= n; i++) |
用序列操作、以及映射的方式来讲这两个 for 语句所表达的东西,是如下一段有可能看起来觉得很绕的话:
对序列 (1 ~ n)
做一次映射:对这个序列里的每个 i,对序列(1 ~ i-1)
再做一次做映射,生成序对(list i j)
。将所有序对用 append
积累起来,得到一个序对序列。
1 | (accumulate append ;用 append 积累所有序对列表 |
将 accumulate append map
这一个程序(映射并用append做序列的表积累)定义为一个过程:
1 | (define (flatmap proc seq) |
过滤找出和为素数的序对:
1 | ;判断素数 |
生成一个三元组:(i, j, i + j)
,代表 i 和 j 是一个和为素数的序对。
1 | (define (make-pair-sum pair) |
整合起来的过程是:
1 | (define (prime-sum-pairs n) ; |
这个例子讲完了。是不是很神奇呢
下一个例子:全排列:
1 | (define (permutations s) |
对比一下C语言的全排列:
1 |
|