我写了一个函数,它已经找到了列表的所有子集,并且它可以工作。我正在尝试编写第二个函数,其中我获得了N长度的所有子集,但它不能很好地工作。
这是我的代码:
(define (subset_length_n n lst)
(cond
[(empty? lst) empty]
[else (foldr (lambda (x y) (if (equal? (length y) n) (cons y x) x)) empty (powerset lst))]
))
其中(powerset lst)给出了所有子集的列表。 我是否误解了折叠的目的? 我认为程序会遍历子集列表中的每个元素,将长度与n进行比较,如果相同则将其限制在空列表中,如果不相同则忽略它。
但是(subset_length_n 2(列表1 2 3))给我(列表(列表1 2)1 2 3)当我想要(列表(列表1 2)(列表1 3)(列表2 3))
提前致谢
答案 0 :(得分:3)
使用foldr
时,您无需测试输入列表是否为空,foldr
会为您处理。这似乎更适合filter
的工作:
(define (subset_length_n n lst)
(filter (lambda (e) (= (length e) n))
(powerset lst)))
如果必须,可以使用foldr
,但这是一个相当人为的解决方案。你非常接近正确!在您的代码中,只需更改lambda
的参数,而不是(x y)
写(y x)
。看看一个好的缩进和适当的参数名称如何在编写正确的解决方案方面走得很远:
(define (subset_length_n n lst)
(foldr (lambda (e acc)
(if (= (length e) n)
(cons e acc)
acc))
empty
(powerset lst)))
无论如何,它按预期工作:
(subset_length_n 4 '(1 2 3 4 5))
=> '((1 2 3 4) (1 2 3 5) (1 2 4 5) (1 3 4 5) (2 3 4 5))