我试图在Ruby中创建一个方法,如果数字包含在斐波纳契序列中,则返回true;如果不包含,则返回false。
我认为当我返回真或假时我遇到了问题。
有人可以告诉我为什么第一个代码不起作用吗?
def is_fibonacci?(num, array=[0,1])
n = array.length - 1
if array[n] > num
array.include?(num) ? true : false
end
array << array[n] + array[n-1]
is_fibonacci?(num, array)
end
当我运行此代码时,我收到此错误消息。
=&gt; filename.rb:36:在`include?&#39;:中断
def is_fibonacci?(num, array=[0,1])
n = array.length - 1
if array[n] > num
if array.include?(num)
return true
else
return false
end
end
array << array[n] + array[n-1]
is_fibonacci?(num, array)
end
第二个代码有效。
为什么我不能使用
array.include?(num) ? true : false
代码中的?
感谢您的帮助。
答案 0 :(得分:2)
Shivam已经很好地回答了为什么你的第一个版本不起作用的问题。
我只想指出,没有理由将所有计算出的斐波纳契数保留在数组中。这是浪费空间,可能有点低效。因此,您可以将方法简化为:
def fibonacci?(number)
fibos = [0, 1]
fibos << (fibos.shift + fibos.last) while fibos.last < number
fibos.include?(number)
end
答案 1 :(得分:1)
array.include?(num) ? true : false
不起作用的原因是因为您没有return
语句。将其更改为return array.include?(num) ? true : false
。然而,它只会调用另一级递归算法,并最终进入堆栈深度。
作为奖励,这里是使用哈希的着名单行:
fibonacci = Hash.new{ |h,k| h[k] = k < 2 ? k : h[k-1] + h[k-2] }
p fibonacci[2] # => 1
p fibonacci[23] # => 28657
答案 2 :(得分:1)
为什么我不能使用
array.include?(num) ? true : false
语法上这个语句没有错,它应该可以正常工作。 (虽然在代码的上下文中可能会返回SystemStackError: stack level too deep
,因为您没有返回任何值)。
以下是一个例子:
array = [0,1]
num = 1
array.include?(num) ? true : false
# => true
num = 3
array.include?(num) ? true : false
# => false
然而,这是可怕的代码。 .include?
的官方文件明确指出:
如果给定对象存在于self中(即,如果有的话),则返回true object == anObject),否则为false。
这意味着:
num = 1
array.include?(num)
# => true
num = 3
array.include?(num)
# => false
您再次在以下代码中重复相同的错误:
if array.include?(num)
return true
else
return false
end
上述所有代码只能替换为一行:
return array.include?(num)
答案 3 :(得分:1)
在您的第一个版本中,块
if array[n] > num
array.include?(num) ? true : false
end
语法正确(虽然令人讨厌),但语义对您的程序不正确,因为您不会返回结果。您可以在该语句上添加显式return
,也可以使程序的其余部分成为else
子句。以下版本有效,因为默认情况下Ruby返回最后一个执行语句的结果,并且只评估if / else的一个分支:
def is_fibonacci?(num, array=[0,1])
n = array.length - 1
if array[n] > num
array.include?(num)
else
array << array[n] + array[n-1]
is_fibonacci?(num, array)
end
end
答案 4 :(得分:0)
使用@hirolau的哈希概念,我们可以用两行来完成。
def fib?(n)
@fibonacci ||= Hash.new{ |h,k| h[k] = k < 2 ? k : h[k-1] + h[k-2] }
(0..n+1).any? { |x| @fibonacci[x] == n }
end
答案 5 :(得分:0)
Fibonacci数算法可以通过两种方式完成:with和w / o recursion。递归版必须实现memoization以避免算法的指数复杂性。
变式1:
class Fibonacci
def initialize(num)
@num = num
@array = [0,1]
end
def process
return @num if [0,1].include?(@num)
2.upto(@num).each do |i|
@array[i] = @array[i-1] + @array[i-2]
end
@array[@num]
end
end
变式2:
class FibonacciMemoizedRecursion
def initialize(num)
@num = num
@memo = {0 => 0, 1 => 1, 2 => 1}
end
def process
recursion(@num)
end
private
def recursion(a)
return @memo[a] if @memo.include?(a)
@memo[a] = recursion(a-1) + recursion(a-2)
end
end
为了测试我们可以使用MiniTest库:
require 'minitest/autorun'
class FibonacciTest < Minitest::Unit::TestCase
def test_process_1
assert_equal 0, Fibonacci.new(0).process
end
def test_process_2
assert_equal 1, Fibonacci.new(1).process
end
def test_process_3
assert_equal 1, Fibonacci.new(2).process
end
def test_process_4
assert_equal 2, Fibonacci.new(3).process
end
def test_process_5
assert_equal 3, Fibonacci.new(4).process
end
def test_process_6
assert_equal 5, Fibonacci.new(5).process
end
def test_process_7
assert_equal 8, Fibonacci.new(6).process
end
def test_process_8
assert_equal 13, Fibonacci.new(7).process
end
end