Functional programming I';I’我正在努力理解这段方案代码,有人能给我解释一下吗?

Functional programming I';I’我正在努力理解这段方案代码,有人能给我解释一下吗?,functional-programming,scheme,Functional Programming,Scheme,我在互联网上发现了这个方案代码,它输出所有给定列表的子集,有人能解释它是如何工作的吗 (定义(子集)(如果为空) (列表()) 让(rest(子集(cdrs)))(追加rest(map(lambda(x)(cons(cars)x))rest(())())) (子集(a、b、c)) 您确实需要格式化它: (define (subsets s) (if (null? s) (list ()) (let ((rest (subsets (cdr s))))

我在互联网上发现了这个方案代码,它输出所有给定列表的子集,有人能解释它是如何工作的吗

(定义(子集)(如果为空)
(列表())
让(rest(子集(cdrs)))(追加rest(map(lambda(x)(cons(cars)x))rest(())()))
(子集(a、b、c))

您确实需要格式化它:

(define (subsets s)
  (if (null? s)
      (list ())
      (let ((rest (subsets (cdr s))))
        (append rest
                (map (lambda (x)
                       (cons (car s) x))
                     rest)))))
它所做的是为参数
'()
返回
(())

对于单元素参数,例如
”(b)
if将
rest
绑定到每个元素的子集,执行第一个元素。。它不是元素,因此
rest
(())
,然后它返回一个列表,其中包含
rest
中的所有元素,以及前面添加了
b
rest
的每个列表元素。因此,
(()(b))

对于双元素参数,例如
”(ab)
它将
rest
绑定到除第一个元素之外的每个元素的子集。这是
(b)
,因此我们从上面知道它是
(()(b))
,我们知道它将使用这些元素以及在开头添加
a
的每个元素:
(()(b)(a)(b))


我可以继续讲下去,但我猜你明白了吗?

是的,我非常感谢,不过有一部分仍然困扰着我。(附加rest(map(lambda(x)(cons(car s)x))rest))我看得越多,就越应该看到重复的字符,但我没有。你能更详细地解释一下这一部分吗?@firelmomo如果
rest
包含
(()(b))
,那么前两个元素将是该元素,后两个将由map处理,并在每个元素前面添加一个元素。例如,我的示例中的
(()(b)(a)(ab))
没有重复项。获取duplucates的唯一方法是参数
s
具有重复项。显然,您不知道Scheme,所以您可能应该在您知道的语言中找到相同的代码。@FIERELMOMOM这里有两个函数,您需要了解每个函数的作用。函数append接受两个列表并将它们连接起来。现在在(附加rest(map(lambda(x)(cons(cars s)x)rest)),append函数的第一个参数是'rest'本身。append函数的第二个参数是一个list,它反过来是map函数的输出,它将lambda应用于'rest'以创建一个新的list,它将通过append与原始的'rest'连接。你必须一点一点地分解它,看看发生了什么我对它很陌生计划,但你帮了很多忙。我现在完全知道它是如何运作的。谢谢。