【发布时间】:2016-09-06 20:41:34
【问题描述】:
我需要改进这个算法的性能。我相信答案在于皮萨诺时期的应用。
此算法必须返回从 f(m) 到 f(n) 的 fib 数之和的最后一位。
这是我目前所拥有的:
def fib(n)
a = []
a << 0 << 1
(n+1).times do |i|
a << a[-1] + a[-2]
end
a[n]
end
def fib_partial_sum(m, n)
if n == m
fib(m) % 10
else
m = fib(m + 1) - 1
n = fib(n + 2) - 1
(n - m) % 10
end
end
if __FILE__ == $0
m, n = gets.split().map(&:to_i)
puts "#{fib_partial_sum(m, n)}"
end
任何 fib num 的最后一位数字每 60 个数字重复一次。因此,我们可以这样做,n, m = n % 60, m % 60。在输入 567717153638 567717153638 上进行了改进,但还没有完全实现:
def fib(n)
a = []
a << 0 << 1
(n+1).times do |i|
a << a[-1] + a[-2]
end
a[n]
end
def fib_partial_sum(m, n)
if n == m
fib(m)
else
m = m % 60
n = n % 60
m = fib(m + 1) - 1
n = fib(n + 2) - 1
(n - m) % 10
end
end
if __FILE__ == $0
m, n = gets.split().map(&:to_i)
puts "#{fib_partial_sum(m, n)}"
end
【问题讨论】:
-
这应该在code review 上吗?除非它是不工作的代码。标题表明确实如此,但质疑性能。
-
顺便问一下,你有理由在
fib上使用数组吗?您的函数基本上返回一个数字;您可以使用两个临时变量而不是数组轻松地做同样的事情(它具有分配/重新分配和垃圾收集的开销以及更大的内存占用)。 -
斐波那契数的最后一位数字每六十个数字重复一次,因此您可以将 n 和 m 替换为 n % 60 和 m % 60。(您实际上可以只使用最终数字序列的数组,但是您可能正在尝试学习算法技术,所以这可能不是您想要的。)
-
@matthewalexander 该输入失败,因为您仅更改了
fib_partial_sum中的else,在本例中为n = m。将if正文更改为fib(m % 60),它应该可以工作。 -
"Any insight is greatly appreciated."也是不可取的。虽然很高兴表达对帮助的感谢,但作为参考书而不是讨论板,SO 有更正式的立场。把它想象成一本教科书或食谱,并据此编写。一些熟悉和友好是受欢迎的,但签名、问候和感谢不会被删掉。