0

所以我试图在方案中迭代地解决 collat​​z 函数,但我的测试用例一直显示为

(define (collatz n)   
    (define (collatz-iter n counter)
            (if (<=  n 1)
                1
            (if (even? n)  (collatz-iter (/ n 2) (+ counter 1))
                           (collatz-iter (+ (* n 3) 1) (+ counter 1)) 
            )
            )
    )
)

但是,我的测试用例不断导致“#[constant 13 #x2]”。我写错了什么,如果有的话?

4

3 回答 3

4

你忘记打电话了collatz-iter。此外,不清楚你打算用 做什么counter,你只是增加它,但从不实际使用它的值——你的过程总是会返回1(假设 Collat​​z 猜想是真的,这似乎很可能)。

我猜你打算退回柜台,所以这里是如何修复你的程序:

(define (collatz n)
  (define (collatz-iter n counter)
    (if (<= n 1)
        counter ; return the counter
        (if (even? n)
            (collatz-iter (/ n 2) (+ counter 1))
            (collatz-iter (+ (* n 3) 1) (+ counter 1)))))
  (collatz-iter n 1)) ; call collatz-iter

这就是它在wikipedia中的示例的工作方式:

(collatz 6)
=> 9

(collatz 11)
=> 15

(collatz 27)
=> 112

所以基本上我们正在计算给定数字的 Collat​​z 序列的长度。

于 2013-10-10T01:48:44.543 回答
2

您应该正确缩进您的代码。使用适当的格式,它是

(define (collatz n)   
  (define (collatz-iter n counter)
    (if (<=  n 1)
        1
        (if (even? n)
            (collatz-iter (/ n 2) (+ counter 1))
            (collatz-iter (+ (* n 3) 1) (+ counter 1))))))

这显然没有要执行的正文形式,只是一个内部定义。您需要添加对 的调用collatz-iter,如下所示:

(define (collatz n)   
  (define (collatz-iter n counter)
    (if (<=  n 1)
        1
        (if (even? n)
            (collatz-iter (/ n 2) (+ counter 1))
            (collatz-iter (+ (* n 3) 1) (+ counter 1)))))
  (collatz-iter n 1))

(我不确定你的初始counter值应该是多少。我假设1它是合理的,但也许它应该为零?)更好的是,由于它只是调用的主体collatz-iter,你可以使它成为一个命名的 let,即更像你的原始代码:

(define (collatz n)
  (let iter ((n n) (counter 1))
    (if (<=  n 1)
        1
        (if (even? n)
            (iter (/ n 2) (+ counter 1))
            (iter (+ (* n 3) 1) (+ counter 1))))))

这有点像将内部定义与对本地函数的单个调用相结合。但是,一旦你完成了这个,你会看到它总是返回1,当它最终到达基本情况时(当然,假设 Collat​​z 猜想是真的)。解决这个问题,你最终会得到:

(define (collatz n)
  (let iter ((n n) (counter 1))
    (if (<=  n 1)
        counter
        (if (even? n)
            (iter (/ n 2) (+ counter 1))
            (iter (+ (* n 3) 1) (+ counter 1))))))
于 2013-10-10T01:48:53.303 回答
2

当我尝试在 Racket 中运行您的代码时,出现错误:

在一系列内部定义之后没有表达式

这告诉我们该collatz函数包含collatz-iter定义,但没有表达式来调用它(除了递归调用 in collatz-iter)。这可以通过(collatz-iter n 0)collatz.

但是,当您运行程序时,它总是返回 1。不是很有趣。相反,如果您更改它以返回值,counter您可以看到序列达到 1 需要多少步。

(define (collatz n)   
    (define (collatz-iter n counter)
            (if (<=  n 1)
                counter
            (if (even? n)  (collatz-iter (/ n 2) (+ counter 1))
                           (collatz-iter (+ (* n 3) 1) (+ counter 1)) 
            )
            )
    )
  (collatz-iter n 0)
)

我们可以对照 Wikipedia Collat​​z 猜想文章中给出的几个例子来检查它。

> (collatz 6)
8
> (collatz 11)
14
> (collatz 27)
111
> 
于 2013-10-10T01:45:40.553 回答