【问题标题】:Generate all possibilities in scheme from a list从列表中生成方案中的所有可能性
【发布时间】:2013-04-05 22:14:51
【问题描述】:

我有一个子列表:

((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.

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

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

【问题讨论】:

    标签: list scheme


    【解决方案1】:

    您正在描述列表列表的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,这里有一个使用标准程序的普通实现;它应该适用于定义fold-right-like 过程的任何 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))
    

    【讨论】:

    • for*/list: 未定义;无法引用未定义的标识符我应该导入一些东西吗?
    • ... 所以,你没有使用 Racket :( 。我可以将上面的代码翻译成更中性的 Scheme 方言,但这需要我一段时间。
    • 完美!谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多