我有一份子列表:
((a b c) (e f) (z h))
我想生成这样的东西:
((a e z) (a f z) (a e h) (a f h) (b e z) (b e h) ... ) and so on.
在给定子列表列表的情况下,我希望生成包含每个输入子列表中元素的子列表的所有可能性。
我怎样才能得到这个输出?
答案 0 :(得分:5)
您正在描述列表列表的cartesian product,这是一个可能的实现(适用于Racket):
(define (cartesian-product lsts)
(foldr (lambda (lst acc)
(for*/list ((x (in-list lst))
(y (in-list acc)))
(cons x y)))
'(())
lsts))
现在,如果你没有使用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))
无论哪种方式,它都按预期工作:
(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))