我需要为powerset写一个递归函数,但是我不能使用mapcar,loop。
到目前为止,这是我的代码:
(defun parts (L)
(cond
((null L)'(nil))
(T
(let ((PXs (parts (cdr L))))
(append PXs (add(car L) PXs))
)
)
)
)
(defun add (E Cs)
(cond
(
(null (cdr Cs))
(list(cons E Cs))
)
(T
(append(list(cons E (list (car Cs)))) (addE (cdr Cs)))
)
)
)
但(部分(' 1 2 3))的结果是:
(NIL (3 NIL) (2 NIL) (2 (3 NIL)) (1 NIL) (1 (3 NIL)) (1 (2 NIL)) (1 (2 (3 NIL))))
我找到了这个方法
(defun powerset (list)
(let ((x (car list)))
(if x
(let ((p (powerset (cdr list))))
(append p (mapcar (lambda (list) (cons x list)) p)))
'(()))))
(powerset(' 1 2 3))的结果是:
(NIL (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))
但是我无法使用mapcar,我在代码中找不到问题,是否有替代功能mapcar?
答案 0 :(得分:3)
这是一个可能的解决方案:
(defun parts (l)
(if (null l)
'(())
(add (car l) (parts (cdr l)))))
(defun add (x pset)
(if (null pset)
nil
(cons (car pset)
(cons (cons x (car pset))
(add x (cdr pset))))))
(parts '(1 2 3)) ; => (NIL (1) (2) (1 2) (3) (1 3) (2 3) (1 2 3))
函数add
以这种方式将元素x添加到powerset:
函数parts
递归地构建列表的powerset,通过将其中一个元素添加到由包含空列表的列表(空集的powerset)构成的powerset中。
答案 1 :(得分:2)
问题:我们不能使用:
(mapcar (lambda (list) (cons x list)) p)
解决方案:
(pairlis (make-list (length p) :initial-element x) p)
也就是说,我们制作一个与p
长度相同的列表,其中包含x
值的重复。然后我们" zip-cons" p
使用pairlis
:
;; understanding pairlis:
(pairlis '(a b c) '(1 2 3)) -> { either: ((a . 1) (b . 2) (c . 3))
{ or: ((c . 3) (b . 2) (a . 1))
pairlis
,只给出两个参数(没有 alist ),实际上是(mapcar #'cons list1 list2)
伪装,list1
和{{1}加上限制必须具有相同的长度,结果可以是向前或向后的顺序。