了解流中的递归

时间:2018-09-01 08:44:58

标签: scala

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

  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的最后一个值?请告诉我我是否缺少某些东西

2 个答案:

答案 0 :(得分: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, ...)

请注意,在每个索引处,在前两个索引之后,新元素是2个先前元素的总和,但是必须先实现这些先前元素,然后才能到达此处,所以可以。这是一个潜在的无限级数,但是Stream仅在请求时计算(实现)一个元素,因此未被请求的元素尚不存在,因此它们不会占用任何内存。 / p>

答案 1 :(得分:0)

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(","))
}