如何在Scala中生成列表,其中每个项目取决于前面的项目

时间:2014-10-13 13:16:23

标签: scala recursion functional-programming

说,我有一个递归规则:

f(0) = 2
f(n) = f(n-1) * 3 - 2

我需要为n∈[0,10]生成一个列表。

如果我对f(10)感兴趣,我可以像这样使用foldLeft

(1 to 10).foldLeft(2)((z, _) => z * 3 - 2)

我希望以简洁实用的方式实现以下目标:

val list = new ListBuffer[Int]
list += 2
(1 to 10).foreach {
    list += list.last * 3 - 2
}

解决方案是什么?

2 个答案:

答案 0 :(得分:4)

您可以使用Stream懒惰且功能性地生成此列表:

  val stream: Stream[Int] = {
    def next(i: Int): Stream[Int] = {
      val n = i * 3 - 2
      n #:: next(n)
    }
    2 #:: next(2)
  }

  println(stream.take(11).toList)
  //prints List(2, 4, 10, 28, 82, 244, 730, 2188, 6562, 19684, 59050)

答案 1 :(得分:3)

多种方法之一涉及使用scanLeft如下,

(1 to 10).scanLeft(2)( (acc,_) => acc*3-2)

这将函数应用于最新(累积)结果。

<强>更新

另请考虑此Iterator

val f = Iterator.iterate(2)(_*3-2)

等等

(1 to 10).map(_ => f.next)

对于大量迭代,初始值2: Int可以转换为BigInt(2),以避免溢出,例如

(1 to 100).map(_ => f.next)