18

次の関数を実装しようとしていますが、stack level too deep (SystemStackError)エラーが発生し続けます。

問題が何であるかについてのアイデアはありますか?

def fibonacci( n )
    [ n ] if ( 0..1 ).include? n
    ( fibonacci( n - 1 ) + fibonacci( n - 2 ) ) if n > 1
end

puts fibonacci( 5 )
4

27 に答える 27

44

これを試して

def fibonacci( n )
  return  n  if ( 0..1 ).include? n
  ( fibonacci( n - 1 ) + fibonacci( n - 2 ) )
end
puts fibonacci( 5 )
# => 5

この投稿もチェックしてくださいフィボナッチワンライナー

その他.. https://web.archive.org/web/20120427224512/http://en.literateprograms.org/Fibonacci_numbers_(Ruby)

あなたは今、多くの解決策で攻撃されています:)

あなたの解決策の問題について

またはn_ 0_1

add最後と次ではない最後の2つの数字

新しい修正版

def fibonacci( n )
    return  n  if n <= 1 
    fibonacci( n - 1 ) + fibonacci( n - 2 )
end 
puts fibonacci( 10 )
# => 55

一発ギャグ

def fibonacci(n)
   n <= 1 ? n :  fibonacci( n - 1 ) + fibonacci( n - 2 ) 
end
puts fibonacci( 10 )
# => 55
于 2012-08-29T13:07:53.230 に答える
19

これが私が思いついたものです。これはより簡単です。

def fib(n)
  n.times.each_with_object([0,1]) { |num, obj| obj << obj[-2] + obj[-1] }
end
fib(10)
于 2012-09-25T15:57:14.760 に答える
13

このアプローチは高速で、メモ化を利用します。

fib = Hash.new {|hash, key| hash[key] = key < 2 ? key : hash[key-1] + hash[key-2] }

fib[123] # => 22698374052006863956975682

このハッシュの初期化がどのように機能するか疑問に思っている場合は、以下をお読みください。

https://ruby-doc.org/core/Hash.html#method-c-new

于 2017-11-30T19:25:36.147 に答える
11

これはフィボナッチを計算する方法ではありません。比較的小さなns では失敗する巨大な再帰ツリーを作成しています。次のようなことをお勧めします。

def fib_r(a, b, n)
  n == 0 ? a : fib_r(b, a + b, n - 1)
end

def fib(n)
  fib_r(0, 1, n)
end

p (0..100).map{ |n| fib(n) }
于 2012-08-29T14:56:19.600 に答える
5

再帰は非常に遅いです。これはより高速な方法です

a = []; a[0] = 1; a[1] = 1
i = 1
while i < 1000000
    a[i+1] = (a[i] + a[i-1])%1000000007
    i += 1
end

puts a[n]    

これは O(1) ですが、行列累乗を使用できます。これは私の実装の 1 つですが、Java => http://pastebin.com/DgbekCJMにありますが、行列 exp. の O(8logn) です。高速倍加と呼ばれるアルゴリズム。高速倍増の Java 実装を次に示します。

class FD {

    static int mod = 1000000007;

    static long fastDoubling(int n) {
        if(n <= 2) return 1;
        int k = n/2;
        long a = fastDoubling(k+1);
        long b = fastDoubling(k);
        if(n%2 == 1) return (a*a + b*b)%mod;
        else return (b*(2*a - b))%mod;
}

しかし、カラツバ乗算を使用すると、両方の行列 exp. 高速倍増ははるかに高速になりますが、高速倍加は行列 exp を打ち負かします。一定の要因により、ここではあまり徹底的になりたくありませんでした。しかし、私は最近、フィボナッチ数について多くの研究を行っており、私の研究が学びたい人に役立つことを願っています;)。

于 2013-02-17T14:01:24.790 に答える
4

これはかなり簡単だと思います:

def fibo(n) a=0 b=1 for i in 0..n c=a+b print "#{c} " a=b b=c end

end
于 2014-12-06T19:46:05.210 に答える
4
PHI = 1.6180339887498959
TAU = 0.5004471413430931

def fibonacci(n)
  (PHI**n + TAU).to_i
end

再帰は必要ありません。

于 2016-09-06T12:17:06.980 に答える
3

ライン内で最速かつ最小のソリューション:

fiby = ->(n, prev, i, count, selfy) {
  i < count ? (selfy.call n + prev, n, i + 1, count, selfy) : (puts n)
}
fiby.call 0, 1, 0, 1000, fiby

機能的な自撮りパターン:)

于 2014-03-23T18:12:03.190 に答える
2

ルックアップ テーブルを作成するより簡潔なソリューションを次に示します。

fibonacci = Hash.new do |hash, key|
  if key <= 1
    hash[key] = key
  else
    hash[key] = hash[key - 1] + hash[key - 2]
  end
end

fibonacci[10]
# => 55 
fibonacci
# => {1=>1, 0=>0, 2=>1, 3=>2, 4=>3, 5=>5, 6=>8, 7=>13, 8=>21, 9=>34, 10=>55}
于 2015-07-01T05:39:53.217 に答える
1

誰かが今日私に似たようなことを尋ねましたが、彼は特定の数値のフィボナッチ数列を含む配列を取得したいと考えていました。例えば、

fibo(5)  => [0, 1, 1, 2, 3, 5]
fibo(8)  => [0, 1, 1, 2, 3, 5, 8]
fibo(13) => [0, 1, 1, 2, 3, 5, 8, 13]
# And so on...

これが私の解決策です。再帰を使用していません。似たようなものを探しているなら、もう1つの解決策:P

def fibo(n)
  seed = [0, 1]
  n.zero? ? [0] : seed.each{|i| i + seed[-1] > n ? seed : seed.push(i + seed[-1])}
end
于 2015-09-11T21:48:05.757 に答える
0

Ruby Fibreの簡単な紹介-

def fibs x, y
  Fiber.new do
    while true do
      Fiber.yield x
      x, y = y, x + y
    end
  end
end

fibs上記では、非常に効率的な方法で計算された無限の数値ストリームを作成しています。単純putsな無限ストリームではないため、ストリームから有限量のアイテムを収集する小さな関数を作成する必要がありますtake

def take t, n
  r = []
  while n > 0 do
    n -= 1
    r << t.resume
  end
  r
end

100最後に、シーケンスの最初の数字を見0てみましょう。1

puts (take (fibs 0, 1), 100)
0
1
1
2
3
5
8
13
21
34
55
.
.
.
31940434634990099905
51680708854858323072
83621143489848422977
135301852344706746049
218922995834555169026
于 2021-02-11T17:13:54.433 に答える