Infinite streams in Scala

后端 未结 5 1563
忘了有多久
忘了有多久 2021-02-03 17:28

Say I have a function, for example the old favourite

def factorial(n:Int) = (BigInt(1) /: (1 to n)) (_*_)

Now I want to find the biggest value

5条回答
  •  余生分开走
    2021-02-03 18:10

    as @ziggystar pointed out, Streams keeps the list of previously computed values in memory, so using Iterator is a great improvment.

    to further improve the answer, I would argue that "infinite streams", are usually computed (or can be computed) based on pre-computed values. if this is the case (and in your factorial stream it definately is), I would suggest using Iterator.iterate instead.

    would look roughly like this:

    scala> val it = Iterator.iterate((1,BigInt(1))){case (i,f) => (i+1,f*(i+1))}
    it: Iterator[(Int, scala.math.BigInt)] = non-empty iterator
    

    then, you could do something like:

    scala> it.find(_._2 >= Long.MaxValue).map(_._1).get - 1
    res0: Int = 22
    

    or use @ziggystar sliding solution...

    another easy example that comes to mind, would be fibonacci numbers:

    scala> val it = Iterator.iterate((1,1)){case (a,b) => (b,a+b)}.map(_._1)
    it: Iterator[Int] = non-empty iterator
    

    in these cases, your'e not computing your new element from scratch every time, but rather do an O(1) work for every new element, which would improve your running time even more.

提交回复
热议问题