返回计算总和的值

时间:2016-09-09 09:24:33

标签: scala scala-collections

这是一个计算Fibonacci序列的Scala流:

    import scala.math.BigInt

    object fib extends App {

      val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(
        fibs.tail).map(n => {
          n._1 + n._2
        })
    }
  fibs take 5 foreach println
  fibs take 6 foreach println

src:http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Stream

不是取顺序中的前n个数字,而是如何使用流对前n个数进行求和,并返回这个数?

我可以像这样介绍var sum

object fib extends App {

    var sum = 3;
  val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map(n => {

      sum = n._1.toInt + n._2.toInt
      n._1 + n._2

    })

  fibs take 5 foreach println

}

然后以某种方式检查这个总和值。但这不是一个好的解决方案。

更新:我正在尝试提供计算此总和的求和值和返回值,而不是实际流的总和。

因此takeSum(7)将返回'0,1,1,2,3'

假设n值sum将包含fib序列的子集

3 个答案:

答案 0 :(得分:4)

您可以在sum上使用Stream - 方法。它适用于所有可用隐式Numeric[T]实现的类型(例如IntLongDoubleBigInt等等。

fibs.take(5).sum

答案 1 :(得分:0)

def takeSum(n:Int) = fib.scanLeft(List[BigInt]()){(b,a)=> a::b}
                        .find(_.sum==n)
                        .get
                        .reverse
 takeSum(7)  //> res0: List[BigInt] = List(0, 1, 1, 2, 3)

scanLeft构建流的前缀(前缀顺序相反),然后只需找到具有正确总和的前缀即可。如果你的假设是n值将是fib序列子集的总和无效,它将不会终止!如果重要的话,您可以将其更改为>=

答案 2 :(得分:0)

听起来你想要的东西......

fibs.takeWhile(f => fibs.takeWhile(_ <= f).sum <= n)

...其中n是目标总和。

这不是一个非常有效的实施,但我认为它完成了工作。

或者,或者。

fibs.take( fibs.tail.scan(0:BigInt)(_+_).indexWhere(_>n) )

稍微冗长一点,但重复一点努力。