我试图实现以下功能,但它一直给我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 )
答案 0 :(得分:38)
试试这个
def fibonacci( n )
return n if ( 0..1 ).include? n
( fibonacci( n - 1 ) + fibonacci( n - 2 ) )
end
puts fibonacci( 5 )
# => 5
检查此帖子Fibonacci One-Liner
以及更多.. https://web.archive.org/web/20120427224512/http://en.literateprograms.org/Fibonacci_numbers_(Ruby)
你现在受到许多解决方案的轰炸:)
关于你的解决方案中的问题
如果n
或0
1
和add
最后两个数字不是最后一个
新修改版
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
答案 1 :(得分:16)
这是我想出的东西,我发现这更直接。
def fib(n)
n.times.each_with_object([0,1]) { |num, obj| obj << obj[-2] + obj[-1] }
end
fib(10)
答案 2 :(得分:11)
这不是你计算斐波纳契的方法,你创建了一个巨大的递归树,对于相对较小的n
来说,它会失败。我建议你做这样的事情:
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) }
答案 3 :(得分:8)
<强>线性强>
module Fib
def self.compute(index)
first = 0
second = 1
index.times do
third = first + second
first = second
second = third
end
first
end
end
使用缓存递归
module Fib
@@mem = {}
def self.compute(index)
if index <= 1
return index
else
@@mem[index] ||= compute(index-1) + compute(index-2)
end
end
end
如果您拨打Fib.compute(256)
答案 4 :(得分:7)
fib = Hash.new {|hash, key| hash[key] = key < 2 ? key : hash[key-1] + hash[key-2] }
fib[123] # => 22698374052006863956975682
如果你想知道这个哈希初始化是如何工作的,请阅读:
答案 5 :(得分:7)
PHI = 1.6180339887498959
TAU = 0.5004471413430931
def fibonacci(n)
(PHI**n + TAU).to_i
end
你不需要递归。
答案 6 :(得分: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),但你可以使用矩阵求幂,这是我的一个实现,但它在java =&gt; 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;
}
然而,使用karatsuba乘法,两个矩阵exp。并且快速加倍变得快得多,但快速加倍节拍矩阵exp。通过一个恒定的因素,我不想在这里非常彻底。但我最近做了很多关于斐波纳契数的研究,我希望我的研究对任何愿意学习的人都有用;)。
答案 7 :(得分:3)
这可能会对你有帮助。
def fib_upto(max)
i1, i2 = 1, 1
while i1 <= max
yield i1
i1, i2 = i2, i1+i2
end
end
fib_upto(5) {|f| print f, " "}
答案 8 :(得分:3)
我认为这很简单:
def fibo(n) a=0 b=1 for i in 0..n c=a+b print "#{c} " a=b b=c end
end
答案 9 :(得分:3)
试试这个oneliner
def fib (n)
n == 0 || n == 1 ? n : fib(n-2) + fib(n-1)
end
print fib(16)
输出:987
答案 10 :(得分:2)
最快和最小的线解决方案:
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
功能性自拍图案:)
答案 11 :(得分:2)
我们可以使用以下算法执行列表fibo系列
def fibo(n)
n <= 2 ? 1 : fibo(n-1) + fibo(n-2)
end
我们可以生成如下的系列
p (1..10).map{|x| fibo(x)}
以下是此
的输出=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
答案 12 :(得分: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...
这是我的解决方案。它没有使用递归。如果你正在寻找类似的东西,还有一个解决方案:P
def fibo(n)
seed = [0, 1]
n.zero? ? [0] : seed.each{|i| i + seed[-1] > n ? seed : seed.push(i + seed[-1])}
end
答案 13 :(得分:1)
1)示例,其中最大元素<100
def fibonachi_to(max_value)
fib = [0, 1]
loop do
value = fib[-1] + fib[-2]
break if value >= max_value
fib << value
end
fib
end
puts fibonachi_to(100)
输出:
0
1
1
2
3
5
8
13
21
34
55
89
2)示例,其中10个元素
def fibonachi_of(numbers)
fib = [0, 1]
(2..numbers-1).each { fib << fib[-1] + fib[-2] }
fib
end
puts fibonachi_of(10)
输出:
0
1
1
2
3
5
8
13
21
34
答案 14 :(得分:1)
我认为是this is the best answer,这是另一个SO帖子提出类似问题的回复。
来自PriteshJ
的接受回答使用了天真的斐波纳契递归,这很好,但是一旦超过第40个左右的元素就变得非常慢。如果你缓存/记忆以前的值并在递归迭代时传递它们会快得多。
答案 15 :(得分:1)
这是Scala中的一个:
object Fib {
def fib(n: Int) {
var a = 1: Int
var b = 0: Int
var i = 0: Int
var f = 0: Int
while(i < n) {
println(s"f(${i+1}) -> $f")
f = a+b
a = b
b = f
i += 1
}
}
def main(args: Array[String]) {
fib(10)
}
}
答案 16 :(得分:1)
这是一个构建查询表的更简洁的解决方案:
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}
答案 17 :(得分:1)
利用记忆力计算斐波那契数的另一种方法:
$FIB_ARRAY = [0,1]
def fib(n)
return n if $FIB_ARRAY.include? n
($FIB_ARRAY[n-1] ||= fib(n-1)) + ($FIB_ARRAY[n-2] ||= fib(n-2))
end
这确保每个斐波那契数只被计算一次,大大减少了对fib方法的调用次数。
答案 18 :(得分:1)
a = [1, 1]
while(a.length < max) do a << a.last(2).inject(:+) end
这将填充a
系列。 (当max&lt; 2)
如果只需要第n个元素,您可以使用Hash.new
fib = Hash.new {|hsh, i| hsh[i] = fib[i-2] + fib[i-1]}.update(0 => 0, 1 => 1)
fib[10]
# => 55
答案 19 :(得分:1)
如果你想为fib编写最快的功能算法,它将不会递归。这是编写解决方案的功能方式较少的几次之一。因为如果使用像
这样的东西,堆栈会重复自我fibonacci( n - 1 ) + fibonacci( n - 2 )
最终n-1和n-2将创建相同的数字,因此将在计算中进行重复。最快的方法是iteratvily
def fib(num)
# first 5 in the sequence 0,1,1,2,3
fib1 = 1 #3
fib2 = 2 #4
i = 5 #start at 5 or 4 depending on wheather you want to include 0 as the first number
while i <= num
temp = fib2
fib2 = fib2 + fib1
fib1 = temp
i += 1
end
p fib2
end
fib(500)
答案 20 :(得分:0)
已经有一段时间了,但你可以编写一个相当优雅和简单的单行函数:
def fib(n)
n > 1 ? fib(n-1) + fib(n-2) : n
end
答案 21 :(得分:0)
这是我用来解决URI Online Judge编程挑战的片段,希望它有所帮助。
def fib(n)
if n == 1
puts 0
else
fib = [0,1]
(n-2).times do
fib << fib[-1] + fib[-2]
end
puts fib.join(' ')
end
end
fib(45)
输出
# => 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733
答案 22 :(得分:0)
加入斐波纳契火车:
正则:
def fib(num)
return num if (num < 2) else fib(num-1) + fib(num-2)
end
使用缓存:
module Fib
@fibs = [0,1]
def self.calc(num)
return num if (num < 2) else @fibs[num] ||= self.calc(num-1) + self.calc(num-2)
end
end
答案 23 :(得分:0)
另一个;)
def fib(n)
f = Math.sqrt(5)
((((1+f)/2)**n - ((1-f)/2)**n)/f).to_i
end
也将方便地添加一些缓存
def fibonacci
@fibonacci ||= Hash.new {|h,k| h[k] = fib k }
end
所以我们将能够得到它
fibonacci[3] #=> 2
fibonacci[10] #=> 55
fibonacci[40] #=> 102334155
fibonacci #=> {3=>2, 10=>55, 40=>102334155}
答案 24 :(得分:0)
一个很好的 Ruby 简介 Fiber -
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
答案 25 :(得分:0)
这个使用记忆化和递归:
def fib(num, memo={})
return num if num <= 1
if memo[num]
return memo[num]
else
memo[num] = fib(num - 2, memo) + fib(num - 1, memo)
end
end