2013-12-23 17 views
5

ストリームドキュメントにフィボナッチ数を取得する良い例があります。スカラーのスライディングストリームを使用してフィボナッチ数を取得するにはどうすればよいですか?

val fibs:Stream[Int] = 0 #:: 1 #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 } 

スライドを使用して実装したいので、以下のようにしました。

val test = 0 #:: 1 #:: Stream.empty 
test.sliding(2).map(_.sum).toStream 

最終行が正しくストリーム(1、?)を取得しますが、私は以下のように、私はエラーを取得することを連結する際に(おそらくスタックオーバーフローをそれが長すぎたので、私は、正確なエラーメッセージを見ることができませんでした)私が3人目のメンバーを取得しようとするとき。

val fibs2:Stream[Int] = 0 #:: 1 #:: fibs2.sliding(2).map(_.sum).toStream 

3つの数字を次のように指定すると、前の2つの数字の合計が計算されます。しかしフィボナッチ数ではありません。

val fibs3:Stream[Int] = 0 #:: 0 #:: 1 #:: fibs3.sliding(2).map(_.sum).toStream 

アイデアや助けをいただければ幸いです。

アップデート

  • 私は、エラーの原因が方法をスライドすると、次の値がメソッドをスライディング方式
  • をのhasNext使用して利用可能かどうかを知る必要がありイテレータは、以前のいずれかの合計を計算する必要があります返すということです疑いますトリボナッチと呼ばれる最初のシーダが与えられれば番号(N = 3)、tetranacci(N = 4)、等

答えて

2

N問題はGroupedIteratorは(によって返されることであると思われます)は熱心です。各スライディングウィンドウを作成するときに、次の要素を強制的に現在のウィンドウに強制します。ここで

は簡単な例です:

import scala.util.Try 

def bad[T]: Stream[T] = throw new RuntimeException("Don't peek!") 

// Should be able to view group of first 2 elements without error, 
// but sliding and grouped both read the 3rd element 
def testA: Stream[Int] = 1 #:: 2 #:: bad 

Try { testA.sliding(2).next } 
// res0: scala.util.Try[scala.collection.immutable.Stream[Int]] = Failure(java.lang.RuntimeException: Don't peek!) 

Try { testA.grouped(2).next } 
// res1: scala.util.Try[scala.collection.immutable.Stream[Int]] = Failure(java.lang.RuntimeException: Don't peek!) 

// Adding an extra element before the bad entry gives 
// sufficient padding for a sliding window of 2 
def testB: Stream[Int] = 1 #:: 2 #:: 3 #:: bad 

Try { testB.sliding(2).next } 
// res2: scala.util.Try[scala.collection.immutable.Stream[Int]] = Success(Stream(1, ?)) 

Try { testB.grouped(2).next } 
// res3: scala.util.Try[scala.collection.immutable.Stream[Int]] = Success(Stream(1, ?)) 

代わりのsliding、あなたがscanLeftを使用することができます。

val fibs: Stream[Int] = 0 #:: fibs.scanLeft(1)(_+_) 

scan機能は一種のfold似ていますが、すべての中間結果を生成します。

  • 1 = 1
  • 0 + 1 = 1
  • 1 + 1 = 2
  • 1 + 2 = 3
  • 2 + 3:だから何あなたが得ることはこれです= 5
  • ...
+0

これは、フィボナッチ数を取得する別の方法です。私は勉強して、練習をしなければなりません。 – nineclue

0

DaoWenの明確な説明は、メソッドができませんスライディング示しました。問題を解く。 Fibonacci numbers of higher orderを計算する別の方法を見つけました。

/* make a Stream of Stream of integer 
input - Stream(0, 1) 
output - Stream(0, 1), Stream(1, 1), Stream(1, 2), Stream(2, 3), ... 
*/ 
def appendSum(initial:Stream[Int]):Stream[Stream[Int]] = 
    Stream.iterate(initial)(s => s.tail :+ s.sum) 

/* fibonacci number of higher order is original Stream + new Stream's last member */ 
def nbonacci(n:Int) = { 
    val inits = Stream.continually(0).take(n-1) :+ 1 
    inits.append(appendSum(inits).tail.map(_.last)) 
} 

/* print out first 20 members of fibonacci, tribonacci, tetrabonacci numbers */ 
(2 to 4).foreach(n => {println(s"$n -----"); nbonacci(n).take(20).foreach(println(_))}) 

スライダが返された場合は、はるかにクリーンで、スピードが向上する可能性があります。

関連する問題