【发布时间】:2014-06-30 07:18:52
【问题描述】:
如何转换整数的 Scala 流,以便我们有一个新的 Stream,其中元素是该元素和前一个元素的总和。
例如,如果输入流是 1, 2, 3, 4 ... 那么输出流是 1, 3, 5, 7。
还有第二个问题,如何使总和在输出流中使用前一个,以便输出为 1, (2+(1)), (3+(2+1)), (4 +(3+(2+1)))。
【问题讨论】:
如何转换整数的 Scala 流,以便我们有一个新的 Stream,其中元素是该元素和前一个元素的总和。
例如,如果输入流是 1, 2, 3, 4 ... 那么输出流是 1, 3, 5, 7。
还有第二个问题,如何使总和在输出流中使用前一个,以便输出为 1, (2+(1)), (3+(2+1)), (4 +(3+(2+1)))。
【问题讨论】:
只需使用自身的转换版本压缩您的流并将两个元素相加即可。
val s1 = Stream.from(0) // 0, 1, 2, 3, ...
val s2 = Stream.from(1) // 1, 2, 3, 4, ...
val sumOfTwo = s1.zip(s2).map{ case (a,b) => a+b } // 1, 3, 5, 7, ...
要计算总和,只需使用像折叠但在每一步都返回元素的扫描函数。
val totalSum = s1.scan(0)((ctr, el) => ctr + el) // 0, 1, 3, 6, 10, ...
【讨论】:
This answer 使用一个变量代替scan() 来计算累积和。示例程序:
import scala.collection.immutable.Stream
object Main extends App {
// 1, 2, 3, ...
val naturals = Stream.from(1)
// cumulative sum (see https://stackoverflow.com/a/8567134/1071311)
def sumUp(s : Stream[Int], acc : Int = 0) : Stream[Int] =
Stream.cons(s.head + acc, sumUp(s.tail, s.head + acc))
val firstFive = sumUp(naturals, 0).take(5)
firstFive.foreach(println _)
}
输出:
1
3
6
10
15
【讨论】: