Scala 单位类型,斐波那契递归深度函数

标签 scala recursion fibonacci

所以我想在 scala 中编写一个斐波那契函数,输出如下所示的树:

fib(3)
| fib(2)
| | fib(1)
| | = 1
| | fib(0)
| | = 0
| = 1
| fib(1)
| = 1
= 2

我当前的代码如下:

 var depth: Int = 0
  def depthFibonacci(n:Int, depth: Int): Int={
    def fibonnaciTailRec(t: Int,i: Int, j: Int): Int = {
      println(("| " * depth) + "fib(" + t + ")")
      if (t==0) {
        println(("| " * depth) + "=" + j)
        return j
      }
      else if (t==1) {
        println (("| " * depth) + "=" + i)
        return i
      }
      else {
        depthFibonacci(t-1,depth+1) + depthFibonacci(t-2,depth+1)
      }
    }
    fibonnaciTailRec(n,1,0)
  }
  println(depthFibonacci(3,depth))

运行时,看起来像:

fib(3)
| fib(2)
| | fib(1)
| | =1
| | fib(0)
| | =0
| fib(1)
| =1
2

正如您所看到的,任何大于 1 的斐波那契数末尾都没有“=”,并且我无法在深度斐波那契函数中实现此功能,否则类型将变为 Unit。我该如何解决这个问题?

最佳答案

这接近你想要的吗?

def depthFib(n:Int, prefix:String = ""):Int = {
  println(s"${prefix}fib($n)")
  val res = n match {
    case x if x < 1 => 0
    case 1 => 1
    case _ => depthFib(n-1, prefix+"| ") +
              depthFib(n-2, prefix+"| ")
  }
  println(s"$prefix= $res")
  res
}

用法:

depthFib(3)

堆栈安全

事实证明,即使没有适当的尾调用递归,我们也可以通过使用标准库中的 TailCalls 来实现尾调用消除。

我们从 ScalaDocs page 上找到的斐波那契实现开始并添加 3 个策略性放置的 println() 语句。

import scala.util.control.TailCalls._

def fib(n: Int, deep:Int=0): TailRec[Int] = {
  println(s"${"| "*deep}fib($n)")
  if (n < 2) {
    println(s"${"| "*deep}= $n")
    done(n)
  } else for {
    x <- tailcall(fib(n-1, deep+1))
    y <- tailcall(fib(n-2, deep+1))
  } yield {
    println(s"${"| "*deep}= ${x+y}")
    x + y
  }
}

用法:

fib(3).result

但事情并不完全像看上去的那样。

val f3 = fib(3)  // fib(3)
println("Wha?")  // Wha?
f3.result        // | fib(2)
                 // | | fib(1)
                 // | | = 1
                 // | | fib(0)
                 // | | = 0
                 // | = 1
                 // | fib(1)
                 // | = 1
                 // = 2

这就是依赖副作用来获得结果的危险。

关于Scala 单位类型,斐波那契递归深度函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65862233/

相关文章:

c++ - 我们可以在C++的递归函数中定义任何 vector 吗?

jsf-2 - JSF : how prevent stackoverflow due to recursion during build phase (despite rendered test)

java - 如何在子级内部显示实体细节而不导致无限递归

c - Codechef 问题 : modified Fibonacci series. 的运行时错误是什么错误?

arrays - 两个条件下的 Scala 过滤器

java - 这是将 Java 接口(interface)转换为 Scala 的正确方法吗?

scala - 为什么我不能对 Scala 中的对象调用 asInstanceOf?

scala - Scala 2.10中如何实现惰性val类变量?

lua - 如何在 Lua 中创建斐波那契数列?

Java::为什么这个带有内存的斐波那契数列的实现不起作用?