你好我必须在lisp编程这个功能:
(defun combine-list-of-lsts (lst)...)
所以在执行函数时我应该
(combine-list-of-lsts '((a b c) (+-) (1 2 3 4)))
((A + 1) (A + 2) (A + 3) (A + 4) (A-1) (A-2) (A-3) (A-4) (B + 1) (B + 2) (B + 3) (B + 4) (B-1) (B-2) (B-3) (B-4)(C + 1) (C + 2) (C + 3) (C + 4) (C-1) (C-2) (C-3) (C-4))
我现在拥有的是:
(defun combine-list-of-lsts (lst)
(if (null (cdr lst))
(car lst)
(if (null (cddr lst))
(combine-lst-lst (car lst) (cadr lst))
(combine-lst-lst (car lst) (combine-list-of-lsts (cdr lst))))))
使用此辅助功能:
(defun combine-lst-lst (lst1 lst2)
(mapcan #'(lambda (x) (combine-elt-lst x lst2)) lst1))
(defun combine-elt-lst (elt lst)
(mapcar #'(lambda (x) (list elt x)) lst))
但我得到的是:
((A (+ 1)) (A (+ 2)) (A (+ 3)) (A (+ 4)) (A(-1)) (A(-2)) (A(-3)) (A(-4))...)
我不知道怎么做但没有括号
答案 0 :(得分:2)
首先要看这个案例:
(lirs-list-of-lsts'((a b c)))
应该是什么?也许不是你的函数返回...
然后我会看一下函数combine-list-of-lsts
。您需要两个IF
语句吗?
然后查看combine-elt-lst
。你真的想用LIST
吗?它会创建一个新列表。将元素添加到前面会不会更有意义吗?
答案 1 :(得分:1)
通常,当你想将多个参数减少为单个结果时,你需要函数#'reduce。您的列表组合具有名称cartesian n-ary product。
以下功能:
(defun cartesian (lst1 lst2)
(let (acc)
(dolist (v1 lst1 acc)
(dolist (v2 lst2)
(push (cons v1 v2) acc)))))
创建两个提供列表的笛卡尔积作为conses列表,其中#'car是lst1的元素,#'cdr是lst2的元素。
(cartesian '(1 2 3) '(- +))
==> ((3 . -) (3 . +) (2 . -) (2 . +) (1 . -) (1 . +))
但请注意,在此类产品上调用#'cartesian将返回格式错误的结果 - 缺点和元素:
(cartesian (cartesian '(1 2) '(+ -)) '(a))
==> (((1 . +) . A) ((1 . -) . A) ((2 . +) . A) ((2 . -) . A))
这种情况发生了,因为第一组的成员是conses而不是atom。另一方面,列表由conses组成,如果我们颠倒创建产品的顺序,我们可以更接近平面列表,我们的目标是什么:
(cartesian '(1 2)
(cartesian '(+ -) '(a)))
==> ((2 + . A) (2 - . A) (1 + . A) (1 - . A))
要创建正确的列表,我们只需要使用nil来构建每个产品 - 换句话说就是创建另一个产品。
(cartesian '(1 2)
(cartesian '(+ -)
(cartesian '(a) '(nil))))
==> ((2 + A) (2 - A) (1 + A) (1 - A))
包装所有内容:你需要以相反的顺序创建连续列表的笛卡尔积,最后为'(零),使用reduce表达式可以实现什么。最终代码看起来像这样:
(defun cartesian (lst1 lst2)
(let (acc)
(dolist (v1 lst1 acc)
(dolist (v2 lst2)
(push (cons v1 v2) acc)))))
(defun combine-lsts (lsts)
(reduce
#'cartesian
lsts
:from-end t
:initial-value '(nil)))
答案 2 :(得分:0)
还有一种方法可以尝试,
(defun mingle (x y)
(let ((temp nil))
(loop for item in x do
(loop for it in y do
(cond ((listp it) (setf temp (cons (append (cons item 'nil) it) temp)))
(t (setf temp (cons (append (cons item 'nil) (cons it 'nil)) temp))))))
temp))
用法:(mingle '(c d f) (mingle '(1 2 3) '(+ -)))
=>
((F 1 +) (F 1 -) (F 2 +) (F 2 -) (F 3 +) (F 3 -) (D 1 +) (D 1 -) (D 2 +)
(D 2 -) (D 3 +) (D 3 -) (C 1 +) (C 1 -) (C 2 +) (C 2 -) (C 3 +) (C 3 -))