scala - 如何在 Scala 中使用滑动流获取斐波那契数列?

标签 scala stream fibonacci sliding

在 Stream 文档中有一个很好的例子可以获取斐波那契数。

val fibs:Stream[Int] = 0 #:: 1 #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 }

我想通过使用滑动来实现它,所以我尝试了以下方法。
val test = 0 #:: 1 #:: Stream.empty
test.sliding(2).map(_.sum).toStream

最后一行正确获取 Stream(1, ?) 但是当我按如下方式将其连接到上面时,当我尝试获取第三个成员时出现错误(可能是堆栈溢出,我看不到确切的错误消息,因为它太长了) .
val fibs2:Stream[Int] = 0 #:: 1 #:: fibs2.sliding(2).map(_.sum).toStream

如果我给出如下 3 个数字,它会计算前两个数字的总和。但这不是斐波那契数。
val fibs3:Stream[Int] = 0 #:: 0 #:: 1 #:: fibs3.sliding(2).map(_.sum).toStream

任何想法或帮助将不胜感激。

更新
  • 我怀疑错误的原因是滑动方法返回Iterator,需要使用hasNext方法知道下一个值是否可用
  • 如果给定第一个种子,滑动方法应该计算前 n 个数字的任何总和,称为 tribonacci (n=3)、tetranacci (n=4) 等。
  • 最佳答案

    问题似乎是GroupedIterator (由 sliding 返回)过于急切。创建每个滑动窗口时,它会强制当前窗口之后的下一个元素。

    这是一个简单的例子:

    import scala.util.Try
    
    def bad[T]: Stream[T] = throw new RuntimeException("Don't peek!")
    
    // Should be able to view group of first 2 elements without error,
    // but sliding and grouped both read the 3rd element
    def testA: Stream[Int] = 1 #:: 2 #:: bad
    
    Try { testA.sliding(2).next }
    // res0: scala.util.Try[scala.collection.immutable.Stream[Int]] = Failure(java.lang.RuntimeException: Don't peek!)
    
    Try { testA.grouped(2).next }
    // res1: scala.util.Try[scala.collection.immutable.Stream[Int]] = Failure(java.lang.RuntimeException: Don't peek!)
    
    // Adding an extra element before the bad entry gives
    // sufficient padding for a sliding window of 2
    def testB: Stream[Int] = 1 #:: 2 #:: 3 #:: bad
    
    Try { testB.sliding(2).next }
    // res2: scala.util.Try[scala.collection.immutable.Stream[Int]] = Success(Stream(1, ?))
    
    Try { testB.grouped(2).next }
    // res3: scala.util.Try[scala.collection.immutable.Stream[Int]] = Success(Stream(1, ?))
    

    而不是 sliding ,您可以使用 scanLeft :
    val fibs: Stream[Int] = 0 #:: fibs.scanLeft(1)(_+_)
    
    scan功能有点像 fold ,但会产生所有中间结果。所以你得到的是这样的:
  • 0
  • 1 = 1
  • 0 + 1 = 1
  • 1 + 1 = 2
  • 1 + 2 = 3
  • 2 + 3 = 5
  • ...
  • 关于scala - 如何在 Scala 中使用滑动流获取斐波那契数列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20736600/

    相关文章:

    android - 如何使用 facebook-android-sdk 获取 facebook 页面的流

    javascript - 卢卡斯斐波那契数

    java - 原理是什么? Spark 何时处理大于内存容量的数据?

    scala - 将值作为列表附加到 Map

    c - 在子进程中操作流

    c++ - 当 C++ 流打开失败时,您可以获得特定的错误情况吗?

    JavaScript 斐波那契分解

    java - Fibonacci(n) 的这个实现是如何工作的? [递归]

    javascript - 设置要在 Play 中编译的 React 类

    security - 在 Play 2.1 中使用 ajax 进行身份验证