Lisp:如何从列表中包含的列表中获取元素的所有可能组合?

问题描述 投票:0回答:2

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

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

我知道如何使用子列表中的成对元素来获取它(输入 ((1 2) (1 2)) 返回 ((1 1) (2 2)),但这对于弧一致性算法我来说还不够好我正在尝试写作,但我被困住了。

谢谢你。

list algorithm lisp combinations common-lisp
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))

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))
© www.soinside.com 2019 - 2024. All rights reserved.