2011-11-11 5 views
6

スカラーで再帰的ループを書くより良い方法があるのだろうかと思っていました。スカラーで再帰的ループを行う方法

def fib(n: Int) = { 
    def loop(a: BigInt = 0, b: BigInt = 1, n: Int = n): BigInt = { 
    if(n==0) a 
    else loop(b, a+b, n-1) 
    } 
    loop() 
} 

この

def fib(n: Int, a: BigInt = 0, b: BigInt = 1): BigInt = { 
    if(n==0) a 
    else fib(n-1, b, a+b) 
} 

が、その後aとbが露出し、もうメソッドの内部でカプセル化されていないことになるように私はそれを書くことができます。

+0

これはほとんど完了です(最初の例)。内部の 'def'メソッドは、プライベートであることを保証し、テイルケイルのために最適化することもできます。 – huynhjl

+0

2番目のバージョンも末尾再帰です。私は8月にこれらのパラメータをScala Languageメーリングリストのプライベートなものにする方法を追加する可能性について尋ねたところ、耳が聞こえない静寂/興味の欠如に遭遇しました。 http://www.scala-lang.org/node/10736 –

+0

短い答え:いいえ。 –

答えて

3

注:

def fib(n: Int) = (1 to n).foldLeft((BigInt(0),BigInt(1)))((p,_)=>(p._2,p._1+p._2))._1 

別のアプローチは、反復子ベースのソリューションとなり

[編集]:

def fib = Iterator.iterate((0,1)){case (x,y) => (y,x+y)}.map(_._1) 

これにより、無限の数のフィボナッチ数が生成されますが、必要な数だけフィボナッチ数を取ることができます例えば、 fib.take(10).toList

1

ループには独自のスコープがあります。ループを再帰関数に置き換えるときは、明示的なスコープ(内部メソッド)を作成する必要があります。その周りに道はない。これはそれがどのように行われるかです。それについて何も間違っていません。あなたは、多くの場合、このような状況でfoldLeftまたはfoldRightを使用することができます

関連する問題