【SICP读书笔记(五)】练习2.32 --- 递归求集合子集
题目内容:
我们可以将一个集合表示为一个元素互不相同的表,因此就可以将一个集合的所有子集表示为表的表。例如,假定集合为(1,2,3),它的所有子集的集合就是( () (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))。请完成下面过程的定义,它生成所有子集的集合,请解释它为什么能完成这一工作。
(define (subsets s) (if (null? s) (list ()) (let ((rest (subsets (cdr s)))) (append rest (map <??> rest)))))
方法:
用递归思维去看,就会发现出乎意料的简单。设集合S有n个元素,那么S的所有子集就有两种情况:
1、包括元素n
2、不包括元素n
不包括元素n的子集列表就是(subsets (cdr s)),而包括元素n的子集就是将元素n加入到上述集合中的每个子集中去。
(有点类似二项式系数公式)
换言之,<??>的部分应该填入
(lambda (rest) (cons (car s) rest))
注意,由于这个匿名过程定义在subsets内部,所以s对于这个过程而言是自由变量,可以使用。
posted on 2014-12-11 15:27 shadowmydx'sLab 阅读(214) 评论(0) 编辑 收藏 举报