【问题标题】:Permutation of list of lists of booleans in RacketRacket 中布尔值列表的排列
【发布时间】:2020-11-11 10:15:05
【问题描述】:
我想创建一个函数:给定一个自然数,返回一个列表列表,其中包含 n 个命题变量的所有可能值。
例如,给定 n = 3,它应该返回:
(list
(list #false #false #false)
(list #false #false #true)
(list #false #true #false)
(list #false #true #true)
(list #true #false #false)
(list #true #false #true)
(list #true #true #false)
(list #true #true #true))
我知道可能的组合数量是 2^n,但我不知道如何在球拍上解决它。
【问题讨论】:
-
cartesian-product 函数可能会对您有所帮助,特别是 (cartesian-product '(#f #t) '(#f #t) '(#f #t)) 返回与您的 n = 3 示例相同的内容。
标签:
list
boolean
racket
permutation
combinatorics
【解决方案1】:
您可能会执行以下操作:
(define (permutation-of-lists n)
(if (= 1 n)
'((#t) (#f))
(append
(map (λ (p) (cons #t p)) (permutation-of-lists (sub1 n)))
(map (λ (p) (cons #f p)) (permutation-of-lists (sub1 n))))))
这适用于任何n >= 1。您还可以选择添加一个案例来处理n = 0。
这实质上是通过将两个可能的副本附加到为 n - 1 生成的列表中来构建这些列表 - 一个附加 #true 而另一个附加 #false 到前面(我们保留两个副本)。
【解决方案2】:
您可以使用cartesian-product 函数。 (cartesian-product (list #false #true) (list #false #true) (list #false #true)) 返回与您的 n = 3 示例相同的内容。参数中(list #false #true)的副本数应该来自n。
(cartesian-product (list #false #true) ...n)
为此,您可以使用cartesian-product 和apply 在列表中提供任意数量的参数,并使用make-list 来创建包含N 个元素的列表:
(define (permutation-of-lists n)
(apply cartesian-product (make-list n (list #false #true))))
使用它:
> (permutation-of-lists 0)
(list '())
> (permutation-of-lists 1)
(list (list #false) (list #true))
> (permutation-of-lists 2)
(list (list #false #false)
(list #false #true)
(list #true #false)
(list #true #true))
> (permutation-of-lists 3)
(list (list #false #false #false)
(list #false #false #true)
(list #false #true #false)
(list #false #true #true)
(list #true #false #false)
(list #true #false #true)
(list #true #true #false)
(list #true #true #true))