请求实现Scheme(Racket)语言的集合所有子集生成函数
实现Scheme函数求集合的所有子集
嘿,别客气~求集合的所有子集(包括空集)是个非常经典的递归问题,咱们直接从核心思路和代码实现入手:
核心思路
递归的逻辑其实特别直观:对于一个用列表表示的集合,它的所有子集可以分成两类:
- 不包含第一个元素的子集:这部分就是剩余元素组成的集合的所有子集
- 包含第一个元素的子集:把第一个元素添加到「剩余元素的所有子集」里的每一个子集中,就能得到这部分
而递归的终止条件(base case)也很明确:当输入是空列表(空集)时,它的唯一子集就是空集本身,也就是返回 (list nil)。
代码实现
(define (subsets s) (if (null? s) (list nil) (let ((rest (subsets (cdr s)))) (append rest (map (lambda (x) (cons (car s) x)) rest)))))
代码解释
- 首先判断输入列表
s是否为空:如果是空列表,直接返回(list nil)——这是空集的唯一子集。 - 如果列表不为空,先递归计算出
(cdr s)(即去掉第一个元素后的剩余列表)的所有子集,把结果存在rest变量里。 - 用
map函数把第一个元素(car s)加到rest的每个元素前面,得到所有包含第一个元素的子集。 - 最后用
append把「不含第一个元素的子集」和「含第一个元素的子集」合并,就是整个集合的所有子集。
示例验证
比如输入'(1 2),调用(subsets '(1 2))会返回:(nil (2) (1) (1 2))
(子集的顺序可能因递归实现略有不同,但所有子集都已包含,集合的子集是不讲究顺序的)
补充说明
这里默认你的输入列表是无重复元素的(符合集合的定义),如果输入有重复元素,这个函数会生成重复的子集,要是需要去重,可以额外添加去重逻辑,不过那就是另一个小问题啦~
内容的提问来源于stack exchange,提问作者katesh
相关产品推荐
相关产品推荐

