作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我们要计算一些斐波那契数,以 997 为模。
对于 n=500
在 C++ 中,我们可以运行
#include <iostream>
#include <array>
std::array<int, 2> fib(unsigned n) {
if (!n)
return {1, 1};
auto x = fib(n - 1);
return {(x[0] + x[1]) % 997, (x[0] + 2 * x[1]) % 997};
}
int main() {
std::cout << fib(500)[0];
}
在 Python 中
def fib(n):
if n==1:
return (1, 2)
x=fib(n-1)
return ((x[0]+x[1]) % 997, (x[0]+2*x[1]) % 997)
if __name__=='__main__':
print(fib(500)[0])
两者都可以毫无问题地找到答案 996。我们采用模数来保持合理的输出大小,并使用对来避免指数分支。
n=5000
,C++代码输出783,但是Python会报错
RecursionError: maximum recursion depth exceeded in comparison
如果我们添加几行
import sys
def fib(n):
if n==1:
return (1, 2)
x=fib(n-1)
return ((x[0]+x[1]) % 997, (x[0]+2*x[1]) % 997)
if __name__=='__main__':
sys.setrecursionlimit(5000)
print(fib(5000)[0])
那么 Python 也会给出正确的答案。
n=50000
当 Python 崩溃时(至少在我的机器上),C++ 在几毫秒内找到了答案 151。
最佳答案
一个解决方案是蹦床:递归函数不是调用另一个函数,而是返回一个函数,该函数使用适当的参数进行调用。有一个更高一级的循环在循环中调用所有这些函数,直到我们得到最终结果。我可能没有很好地解释它;您可以在网上找到做得更好的资源。
关键是这将递归转换为迭代。我不认为这更快,甚至可能更慢,但递归深度保持较低。
一个实现可能如下所示。我分了对 x
进入 a
和 b
为了清楚起见。然后我将递归函数转换为跟踪 a
的版本。和 b
作为参数,使其尾递归。
def fib_acc(n, a, b):
if n == 1:
return (a, b)
return lambda: fib_acc(n - 1, (a+b) % 997, (a+2*b) % 997)
def fib(n):
x = fib_acc(n, 1, 2)
while callable(x):
x = x()
return x
if __name__=='__main__':
print(fib(50000)[0])
关于python - 为什么 Python 递归如此昂贵,我们能做些什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67988828/
我正在阅读 MongoDB,并试图了解它的最佳用途。我没有看到明确答案的一个问题是哪些操作便宜或昂贵,以及在什么条件下。 你能帮忙澄清一下吗? 谢谢。 最佳答案 人们经常声称 mongodb 的写入速
我正在寻找一个主要来源(或一个非常好的解释)来支持在为 iPhone 编写软件时使用 autorelease 是危险的或过于昂贵的说法。 许多开发者都提出了这种说法,我什至听说 Apple 不推荐它,
我意识到这离微优化领域太远了,但我很想知道为什么调用 DateTime.Now 和 DateTime.UtcNow 如此“昂贵”。我有一个示例程序,它运行几个场景来做一些“工作”(添加到一个计数器)并
我是一名优秀的程序员,十分优秀!