【问题标题】:Understanding recursion in streams理解流中的递归
【发布时间】:2018-09-01 08:44:58
【问题描述】:

我试图理解流中的递归,这令人困惑。我的代码是这样的

  val bigIntFromStream : Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: bigIntFromStream.zip(bigIntFromStream.tail).map{x =>
    println(s"stream = ${bigIntFromStream} + stream.tail = ${bigIntFromStream.tail} + zipped value = ${bigIntFromStream.zip(bigIntFromStream.tail)}")
    println(s"Calculating value for ${x}, {x._1} = ${x._1}, {x._2} = ${x._2}")
    x._1 + x._2}

代码的输出是这样的

0 1 stream = Stream(0, 1, ?) + stream.tail = Stream(1, ?) + zipped value = Stream((0,1), ?)

Calculating value for (0,1), {x._1} = 0, {x._2} = 1
1 stream = Stream(0, 1, 1, ?) + stream.tail = Stream(1, 1, ?) + zipped value = Stream((0,1), ?)

Calculating value for (1,1), {x._1} = 1, {x._2} = 1
2 stream = Stream(0, 1, 1, 2, ?) + stream.tail = Stream(1, 1, 2, ?) + zipped value = Stream((0,1), ?)

Calculating value for (1,2), {x._1} = 1, {x._2} = 2
3 stream = Stream(0, 1, 1, 2, 3, ?) + stream.tail = Stream(1, 1, 2, 3, ?) + zipped value = Stream((0,1), ?)

Calculating value for (2,3), {x._1} = 2, {x._2} = 3
5 stream = Stream(0, 1, 1, 2, 3, 5, ?) + stream.tail = Stream(1, 1, 2, 3, 5, ?) + zipped value = Stream((0,1), ?)

Calculating value for (3,5), {x._1} = 3, {x._2} = 5

我的问题是 x 如何获得 zip 在实际值和它的尾部之间的最后一个值?如果我遗漏了什么,请告诉我

【问题讨论】:

    标签: scala


    【解决方案1】:

    回想一下,Stream 最初是一个单一元素,并承诺在需要时获得更多。即使所有元素都已完全定义,情况也是如此。

    val ns = Stream(1,2,3,4,5)
    //ns: scala.collection.immutable.Stream[Int] = Stream(1, ?)
    

    一个带有自己尾巴的集合有效地将每个元素与其邻居配对。

    val paired = ns zip ns.tail
    //paired: scala.collection.immutable.Stream[(Int, Int)] = Stream((1,2), ?)
    // The rest are (2,3), (3,4) and (4,5), but they haven't been realized yet.
    

    此外,当您索引 Stream 时,它是一个线性运算。换句话说,如果你想要paired(3),代码将逐步遍历(“实现”)paired(0),然后是paired(1),然后是paired(2),最后是paired(3)

    所以你发布的Stream本质上是:

    // This is concept, not code.
    Stream(a=0, b=1, c=a+b, d=b+c, e=c+d, ...)
    

    请注意,在每个索引处,在前两个之后,新元素是前两个元素的总和,但在我们到达这里之前,必须先实现这些前一个元素,所以没关系。这可能是一个无限的进程,但 Stream 仅根据请求计算(实现)一个元素,因此未被请求的元素尚不存在,因此它们不会占用任何内存。

    【讨论】:

      【解决方案2】:
      object Test extends App {
        var bigIntFromStream : Stream[BigInt] = Stream(0,1)
      
        def addItems(n: Int)(x: Stream[BigInt]): Unit = {
          if(n > 0){
            val lastIndex: Int = bigIntFromStream.indices.last
            bigIntFromStream ++= Stream(bigIntFromStream(lastIndex - 1) + bigIntFromStream(lastIndex))
            addItems(n-1)(bigIntFromStream)
          }
        }
      
        addItems(10)(bigIntFromStream)
      
        println(bigIntFromStream.mkString(","))
      }
      

      【讨论】:

        猜你喜欢
        • 2012-07-26
        • 2014-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多