3

我需要在 Common-Lisp 中编写一个函数,该函数接受一个列表列表并返回一个列表,其中包含子列表中元素的所有可能组合。

因此,例如在 ((1 2) (1 2)) 这样的列表上调用函数应该返回像 ((1 1) (1 2) (2 1) (2 2)) 这样的列表。输入列表可以是任意长度,并且不保证子列表具有相同的长度。

我知道如何使用子列表中的配对元素( inputtting ((1 2) (1 2)) 返回 ((1 1) (2 2)))来获得它,但这对于我的弧一致性算法来说还不够好试图写,我被困住了。

谢谢你。

4

2 回答 2

6

如果您不想使用库,这里的代码可以做同样的事情,并且适用于任意数量的列表:

(defun combinations (&rest lists)
  (if (endp lists)
      (list nil)
      (mapcan (lambda (inner-val)
                (mapcar (lambda (outer-val)
                          (cons outer-val
                                inner-val))
                        (car lists)))
              (apply #'combinations (cdr lists)))))

[2]> (combinations '(1 2))
((1) (2))
[3]> (combinations '(1 2) '(3 4))
((1 3) (2 3) (1 4) (2 4))
[4]> (combinations '(1 2) '(3 4) '(5 6))
((1 3 5) (2 3 5) (1 4 5) (2 4 5) (1 3 6) (2 3 6) (1 4 6) (2 4 6))
于 2013-09-08T05:02:47.807 回答
6

wvxvw 删除了他们指向 Alexandria 函数的答案,但它确实提供了一个名称非常相似的函数,它实际上可以执行您想要的操作。而不是alexandria:map-combinations,你需要alexandria:map-product,例如

(apply #'alexandria:map-product #'list '((1 2) (1 2)))

评估为

((1 1) (1 2) (2 1) (2 2))
于 2013-09-07T19:57:10.957 回答