如何获取布尔值的所有组合的列表?

时间:2016-03-15 16:14:55

标签: recursion boolean scheme racket

我想创建以下函数,all-combs,其行为如示例所示。为什么我的代码不起作用?你能解决它还是提供自己的代码?

(all-combs 0)
>> '(())
(all-combs 1)
>> '((0) (1))
(all-combs 2)
>> '((0 0) (0 1) (1 0) (1 1))

(define (all-combs1 n)
  (cond
  [(equal? n 0) '(())]
  [else
    (append (map (lambda (x) (cons 0 x)) (all-combs1 (- 1 n)))
    (map (lambda (x) (cons 1 x)) (all-combs1 (- 1 n))))
 ]))

2 个答案:

答案 0 :(得分:1)

通常情况下,获取所有内容组合的方法是将cartesian-product应用于可能值列表的 n 副本。

将函数应用于 n 重复值的方法是将applymake-list一起使用:

#lang racket

;; for combinations of booleans
(define (all-boolean-combinations n)
  (apply cartesian-product (make-list n '(#t #f))))

;; for combinations of integers 0 through 2
(define (all-0..2-combinations n)
  (apply cartesian-product (make-list n '(0 1 2))))

;; for combinations of any list of possible values
(define (all-combinations n possible-values)
  (apply cartesian-product (make-list n possible-values)))

你的0和1的例子是这样的:

> (all-combinations 0 '(0 1))
'(())
> (all-combinations 1 '(0 1))
'((0) (1))
> (all-combinations 2 '(0 1))
'((0 0) (0 1) (1 0) (1 1))
> (all-combinations 3 '(0 1))
'((0 0 0) (0 0 1) (0 1 0) (0 1 1) (1 0 0) (1 0 1) (1 1 0) (1 1 1))
> (all-combinations 4 '(0 1))
'((0 0 0 0) (0 0 0 1) (0 0 1 0) (0 0 1 1) (0 1 0 0) (0 1 0 1) (0 1 1 0) (0 1 1 1)
  (1 0 0 0) (1 0 0 1) (1 0 1 0) (1 0 1 1) (1 1 0 0) (1 1 0 1) (1 1 1 0) (1 1 1 1))

答案 1 :(得分:0)

你非常接近。问题是你正在切换minuend和substrahend。 (- 1 2)不会1小于2而是-1(- 1 n)显然不是争论的预期顺序。

(define (all-combs n)
  (if (zero? n)
      '(())
      (let ([rest-of-combs (all-combs1 (- n 1))])
        (append (map (lambda (x) (cons 0 x)) rest-of-combs)
                (map (lambda (x) (cons 1 x)) rest-of-combs)))))

我还做了一些额外的不完整修改:

由于您在同一数据集上执行了all-combs1两次,因此对大数字执行效果非常差。通过使用let绑定并使用结果两次来轻松省略它。

由于您的案例分析只有一个谓词,一个后果和一个备选,因此使用if而不是cond更容易阅读它。

equal?可以用于任何数据类型,对于看起来相同的所有内容都可以#t。对于数字,使用eqv?=就足够了,这仅适用于数值。在=中看到(= a b)时,您知道ab应该是数字,而(eqv? a b)可以是数字,字符或符号。使用更具体的过程可能会更快,但报告不需要实现。 (zero? n)(= n 0)的作用相同,但不需要指定第二个操作数,并且稍微更清楚一点。