Stream建立斐波那契数列


Stream 流 是递归的数据结构,包含一个表头(当前元素)和一个表尾(集合的其他部分)。能够利用一个函数和函数的递归调用来构建流。数据结构

Stream.cons(head,tail) head是Stream中的表头,tail是余下的元素函数


例子:给定一个整数值,建立一个连续递增的整数集合ui


scala> def inc(i:Int):Stream[Int] = Stream.cons(i,inc(i+1))
scala> inc(1).take(5).toList
res0: List[Int] = List(1,2,3,4,5)


建立斐波那契数列.net

scala> def fabonacciStream(last:Int,now:Int):Stream[Int] = Stream.cons(now,fabonacciStream(now,last+now))
scala> fabonacciStream(0,1).take(20).toList
res1: List(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765)

思路:Stream中只可以取到头元素,可是斐波那契须要最末端的两个元素

因此递归的函数须要传入最末端的两个元素,计算并放入Stream的末尾scala

fabonacciStream(0,1).take(5) 的计算过程:code

Stream.cons( 1, fabinacciStream( 1, 0+1 => 1)) //List(1)
blog

Stream.cons( 1, Stream.cons( 1, fabinacciStream( 1, 1+1 => 2))) //List(1,1)
递归

Stream.cons( 1, Stream.cons( 1, Stream.cons( 2, fabinacciStream( 2, 1+2=>3)))) //List(1,1,2)
ip

Stream.cons( 1, Stream.cons( 1, Stream.cons( 2, Stream.cons(3, fabinacciStream( 3, 2+3 => 5))))) //List(1,1,2,3)ci

Stream.cons( 1, Stream.cons( 1, Stream.cons( 2, Stream.cons(3, Stream,cons( 5, fabinacciStream( 5, 3+5 =>8)))))) //List(1,1,2,3,5)


还看到另外一种颇有趣的斐波那契数列建立方法

scala>  lazy val fib: Stream[BigInt] = Stream.cons(1, Stream.cons(1, (fib zip fib.tail).map(p => p._1 + p._2)))

scala的zip操做

zip: zip[B](that: GenIterable[B]): List[(A, B)] 与另一个列表进行拉链操做,将对应位置的元素组成一个pair,返回的列表长度为两个列表中短的那个

scala> val list = List(1,2,3,4,5)
scala> list zip list.tail
res2: List[(Int,Int)] = List((1,2),(2,3),(3,4),(4,5))


参考文章

Scala中Stream的应用场景及其实现原理

Scala的Stream

Scala 强大的集合数据操做示例