Scala中尾部递归函数查找第n个Fibonacci数时出错

Scala中尾部递归函数查找第n个Fibonacci数时出错,scala,fibonacci,tail-recursion,Scala,Fibonacci,Tail Recursion,我想实现一个尾部递归函数来获得第n个斐波那契数 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,

我想实现一个尾部递归函数来获得第n个斐波那契数

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)
}
这是我的尝试。对于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)
    }
}
对象斐波那契{
def fib(n:Int):Int={
def go(n:Int,acc:Int):Int=

如果(n您的代码不是尾部递归的,因为它在最内部的go()调用中构建了一个堆栈

解决方案是展平辅助对象,使其也包括前两个术语(而不仅仅是单个术语):


您的问题是,在n>2的情况下,您没有使用“acc”参数

当你调用go(4,0)时,你得到:go(3,go(2,0))

go(2,0)解析为1,然后调用go(3,1),它会变成go(2,go(1,0))

go(1,0)解析为0,然后调用go(2,0),它返回1

你需要在最后一个案例中读到:go(n-1,go(n-2,acc))

正如其他人所指出的,您的函数不是尾部递归的,因为go(n-2,0)调用的结果用于另一个函数调用。如果您打算创建尾部递归函数,请使用“@tailrec”注释,这样当您的函数不是尾部递归时,编译器将给您一个错误


Richard的解决方案是在循环中运行两个累加器:当前总数和前一个总数,在最后拉出其中一个累加器,从而允许函数正确地进行尾部递归。

此解决方案始终返回n Fibonacci数,而不是n+1 Fibonacci数

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)
}

我希望能帮助您将注释添加到一个您打算使用尾部递归的函数中,编译器会告诉您是否在这方面犯了错误。谢谢!显然,本书后面会介绍这个方法。aaaa结果证明它不是尾部递归的。唉……我会处理它。您的解决方案是有意义的,而且是有效的,尽管如此代码应该是
case1=>acc
,否则它将返回第n+1个斐波那契数。