我正在尝试用两种不同的方式在Scheme中实现幂集函数。 一种方法是使用尾递归,我的实现如下:
(define (powerset list)
(if (null? list) '(()) ;; if list is empty, its powerset is a list containing the empty list
(let ((rest (powerset (cdr list)))) ;; define "rest" as the result of the recursion over the rest of list
(append (map (lambda (x) (cons (car list) x)) rest) ;; add the first element of list to the every element of rest (which is a sublist of rest)
rest)))) ;; and append it to rest itself (as we can either use the current element (car list), or not
这种方法是可行的。
另一种方法是使用foldr,但这是我遇到问题的地方。 我的当前实现如下:
(define (powerset-fr list)
(foldr (lambda (element result) ;; This procedure gets an element (and a result);
(if (null? result) ;; if starting with the empty list, there is nothing to "fold over".
(cons '() (cons element result))
(foldr (lambda (inner-element inner-result)
(append (cons element result) inner-result))
'(())
result)))
'() ;; The result is initialized to the empty list,
list)) ;; and the procedure is being applied for every element in the first list (list1)
这样的做法得到的结果很差。
我将简要说明我迄今为止如何解决这个问题:
foldr运行在给定集合中的每个元素上。对于每个元素,我应该向幂集添加一些新元素。这些应该是哪些元素?针对现有幂集中的每个元素,添加一个新元素,在该幂集中附加列表中的当前元素。
这就是为什么我认为我应该以嵌套方式两次使用foldr-一次遍历给定列表中的所有项目,对于每个项目,我使用foldr遍历“result”(当前幂集)中的所有项目。
我面临的问题是空列表(没有任何内容被添加到幂集中),因此添加了“if”部分(而不仅仅是foldr),但它也不能很好地工作。
我想这就是全部。我感觉接近了,但仍然非常具有挑战性,所以欢迎任何帮助。 谢谢!
xs
表示x
的列表,使用xss
表示x
的列表的列表。 - soegaard