从列表中生成方案中的所有可能性

Vla*_*dan 3 scheme list

我有一份子列表:

((a b c) (e f) (z h)) 
Run Code Online (Sandbox Code Playgroud)

我想生成这样的东西:

((a e z) (a f z) (a e h) (a f h) (b e z) (b e h) ... ) and so on.
Run Code Online (Sandbox Code Playgroud)

在给定子列表列表的情况下,我希望生成包含来自每个输入子列表的元素的子列表的所有可能性.

我怎样才能得到这个输出?

Ósc*_*pez 5

您正在描述列表列表中的笛卡尔积,这是一个可能的实现(适用于Racket):

(define (cartesian-product lsts)
  (foldr (lambda (lst acc)
           (for*/list ((x (in-list lst))
                       (y (in-list acc)))
             (cons x y)))
         '(())
         lsts))
Run Code Online (Sandbox Code Playgroud)

现在,如果你没有使用Racket,这里有一个使用大多数标准程序的vanilla实现; 它应该适用于任何定义类似fold-right过程的Scheme解释器:

(define (flatmap f lst)
  (apply append (map f lst)))

(define (cartesian-product lsts)
  (foldr (lambda (lst acc)
           (flatmap (lambda (x)
                      (map (lambda (y)
                             (cons x y))
                           acc))
                    lst))
         '(())
         lsts))
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,它都按预期工作:

(cartesian-product '((a b c) (e f) (z h)))

=> '((a e z) (a e h) (a f z) (a f h) (b e z) (b e h)
     (b f z) (b f h) (c e z) (c e h) (c f z) (c f h))
Run Code Online (Sandbox Code Playgroud)