所以我试图在方案中迭代地解决collatz函数,但我的测试用例一直显示为
(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))
)
)
)
)
但是,我的测试用例会导致“#[常数13#x2]”。我写错了什么,如果有的话?
答案 0 :(得分:4)
您忘了拨打collatz-iter
。此外,你不清楚你打算用counter
做什么,你只是增加它,但从不实际使用它的值 - 你的程序总是返回1
(假设Collatz猜想是真的,这似乎很有可能。)
我猜你打算退回计数器,所以这里是如何解决你的程序:
(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
所以基本上我们计算给定数字的Collatz序列的长度。
答案 1 :(得分:2)
当我尝试在Racket中运行您的代码时,我收到错误:
在内部定义序列之后没有表达
这告诉我们collatz
函数包含collatz-iter
定义,但没有表达式来调用它(除了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 Collatz conjecture文章中提供的一些示例进行检查。
> (collatz 6)
8
> (collatz 11)
14
> (collatz 27)
111
>
答案 2 :(得分: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
,当它最终到达基本情况时(假设Collatz猜想是真的,当然)。解决这个问题,你最终会得到:
(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))))))