我想实现一个尾递归函数来获取 n 的Fibonacci数。
这是我的尝试。它并不像 n = 4或更高版本那样工作。
object Fibonacci {
def fib(n: Int): Int = {
def go(n: Int, acc: Int): Int =
if (n <= 1) 0 + acc
else if (n == 2) 1 + acc
else go(n-1, go(n-2, 0))
go(n, 0)
}
}
问题是,当输入 n = 3时,所需的输出为1,输入 n = 4或更高仍然只返回1.
我注意到的是,如果我定义了另一行&#34;否则如果&#34;,即如果(n == 3)1 + acc,那么我的函数将按预期用于 n < / em> = 4(它将返回&#34; 2&#34;正如预期的那样),但它仍然不适用于 n = 5或更高,我可以&#39;弄清楚原因。
如果我对这个问题的解决方法看起来很奇怪,那是因为这是我到目前为止学到的所有内容,而且应该足以解决手头的问题。
实际上,我并不完全确定上述函数是否可以被视为尾递归,因为我刚刚开始学习它。如果不是,请指出我,我会做出相应的更改。
答案 0 :(得分:3)
您的代码不是尾递归的,因为它在最里面的go()调用中构建了一个堆栈。
解决方案是将帮助者扁平化以包括前两个术语(不只是一个术语):
def fib(n : Int) : Int = {
def go(n: Int, acc:Int, x:Int): Int = n match {
case 0 => acc
case _ => go(n-1, x, acc+x)
}
return go(n, 0, 1)
}
答案 1 :(得分:0)
你的问题是,在n> 2的情况下,你没有使用&#39; acc&#39;参数。
当你打电话给go(4,0)时,你得到:go(3,go(2,0))
go(2,0)解析为1,所以你调用go(3,1),转为go(2,go(1,0))
go(1,0)resovles to 0,所以你调用go(2,0),返回1.
你需要你的最后一个案例来阅读:go(n-1,go(n-2,acc))
正如其他人所说,你的函数不是尾递归的,因为调用go(n-2,0)的结果用于另一个函数调用。如果你打算做一个尾递归函数,请使用&#39; @ tailrec&#39;注释,这样当函数不是尾递归时,编译器会给你一个错误。
理查德的解决方案是在循环周围运行两个累加器:当前总数和前一个总数,最后将其中一个累加出来,从而允许函数正确地尾递归。
答案 2 :(得分:0)
此解决方案始终返回 n 斐波纳契数而不是n + 1斐波纳契数。
def fibonacci (n: Int): Int = {
@tailrec
def go(nextToLast: Int, last: Int, n: Int): Int = n match {
case 0 => 0
case 1 => last
case _ => go(last, nextToLast+last, n-1)
}
go(0, 1, n-1)
}
我希望能帮助