我想创建以下函数,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))))
]))
答案 0 :(得分:1)
通常情况下,获取所有内容组合的方法是将cartesian-product
应用于可能值列表的 n 副本。
将函数应用于 n 重复值的方法是将apply
与make-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)
时,您知道a
和b
应该是数字,而(eqv? a b)
可以是数字,字符或符号。使用更具体的过程可能会更快,但报告不需要实现。 (zero? n)
与(= n 0)
的作用相同,但不需要指定第二个操作数,并且稍微更清楚一点。