如何转换一个由整数组成的Scala流,使我们有一个新的流,其中的元素是这个元素和前一个元素的和。
例如输入流为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, ...
要计算总和,只需使用scan函数,它的作用类似于折叠,但在每一步返回元素。
val totalSum = s1.scan(0)((ctr, el) => ctr + el) // 0, 1, 3, 6, 10, ...
这个答案通过使用一个变量来代替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