Python 如何使用超过极限位的递归?
我想用下面的程序进行递归,但因为输入数字太大(19位)。它在我的程序中抛出一个错误 内存错误:堆栈溢出或递归错误:在比较中超过最大递归深度。我尝试使用Python 如何使用超过极限位的递归?,python,python-3.x,recursion,Python,Python 3.x,Recursion,我想用下面的程序进行递归,但因为输入数字太大(19位)。它在我的程序中抛出一个错误 内存错误:堆栈溢出或递归错误:在比较中超过最大递归深度。我尝试使用 import sys sys.setrecursionlimit(100000) 但这没有帮助。你有什么办法来处理这么大的数字吗? 这是我的全部计划 def recursion(n): return 1 if n < 2 else n * recursion(n - 2) string = str(recursion(1000
import sys
sys.setrecursionlimit(100000)
但这没有帮助。你有什么办法来处理这么大的数字吗?
这是我的全部计划
def recursion(n):
return 1 if n < 2 else n * recursion(n - 2)
string = str(recursion(1000000000000000000))
def递归(n):
如果n<2则返回1,否则返回n*递归(n-2)
string=str(递归(10000000000000000000000))
不幸的是,迭代失败了。但你可以自己做:
def recursion(n):
result = 1
for i in range(2, n+1, 2):
result *= i
return result
如果您真的希望它是递归的,那么您唯一能做的就是增加递归限制和堆栈大小,但这不是一个好主意。不幸的是,这不利于迭代。但你可以自己做:
def recursion(n):
result = 1
for i in range(2, n+1, 2):
result *= i
return result
如果您真的希望它是递归的,那么您唯一能做的就是增加递归限制和堆栈大小,但这不是一个好主意。这是递归的实际限制之一 Python可以防止递归调用的次数,以避免堆栈溢出。这是您看到的
递归错误
:
Python 3.7.4 (default, Aug 13 2019, 20:35:49)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def recursion(n):
... return 1 if n < 2 else n * recursion(n - 2)
...
>>>
>>> string = str(recursion(1000000000000000000))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in recursion
File "<stdin>", line 2, in recursion
File "<stdin>", line 2, in recursion
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded in comparison
Python中解决此问题的惯用方法是使用迭代:
def iteration(n):
result = 1
for i in range(n, 1, -2):
result *= i
return result
不过,使用原始输入(1e18
)运行此示例不会很快终止。随着整数的增长,计算所需的时间越来越长,因为操作需要使用大于64位的整数表示(或CPU能够用单个寄存器表示的位数)
然而,这将是这个问题的python解决方案。这是递归的实际限制之一 Python可以防止递归调用的次数,以避免堆栈溢出。这是您看到的
递归错误
:
Python 3.7.4 (default, Aug 13 2019, 20:35:49)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def recursion(n):
... return 1 if n < 2 else n * recursion(n - 2)
...
>>>
>>> string = str(recursion(1000000000000000000))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in recursion
File "<stdin>", line 2, in recursion
File "<stdin>", line 2, in recursion
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded in comparison
Python中解决此问题的惯用方法是使用迭代:
def iteration(n):
result = 1
for i in range(n, 1, -2):
result *= i
return result
不过,使用原始输入(1e18
)运行此示例不会很快终止。随着整数的增长,计算所需的时间越来越长,因为操作需要使用大于64位的整数表示(或CPU能够用单个寄存器表示的位数)
然而,这将是这个问题的Pythonic解决方案。即使是
n
,您的函数也会计算2*4*6**n
。很容易计算出这与2^(n/2)*(n/2)代码>。例如,2*4*6*8*10=(2*1)*(2*2)*(2*3)*(2*4)*(2*5)
,这就是2^5*(1*2*3*4*5)=32*5代码>。这可以通过函数快速有效地计算:
import math
def f(n):
k = n//2
return 2**k * math.factorial(k)
对于奇数n
,它稍微复杂一些。从数学溢出中看
由,f(n)
渐近等价于sqrt(pi*n)*(n/e)^(n/2)
。插入n=10^18
,并获取结果的base-2日志,您可以看到f(10^18)
大约需要3.6才能存储结果的整数(这可能比您的计算机所能处理的还要多)。即使n
,您的函数也会计算2*4*6**n
。很容易计算出这与2^(n/2)*(n/2)代码>。例如,2*4*6*8*10=(2*1)*(2*2)*(2*3)*(2*4)*(2*5)
,这就是2^5*(1*2*3*4*5)=32*5代码>。这可以通过函数快速有效地计算:
import math
def f(n):
k = n//2
return 2**k * math.factorial(k)
对于奇数n
,它稍微复杂一些。从数学溢出中看
由,f(n)
渐近等价于sqrt(pi*n)*(n/e)^(n/2)
。插入n=10^18
,并获取结果的base-2日志,您可以看到f(10^18)
大约需要3.6才能存储结果的整数(这可能超出了计算机的处理能力).有时递归不是一种有用的方法。除了递归之外,您还有其他方法可供我使用的建议吗?如果您遇到内存错误,并且您的实现是正确的,这几乎肯定意味着您需要更改为非递归方法。10^19递归深度在任何现有计算机上都是不可能的即使除了递归限制问题,我怀疑您是否有内存来保存str(递归(10000000000000000))
或计算递归(10000000000000000)
。使用对数可以验证所涉及的内存是否过大。您试图计算的函数比任何指数函数都增长得快。有时递归不是一种有用的方法。除了递归之外,您还有其他方法可供我使用的建议吗?如果您遇到内存错误,并且您的实现是正确的,这几乎肯定意味着您需要更改为非递归方法。10^19递归深度在任何现有计算机上都是不可能的即使除了递归限制问题,我怀疑您是否有内存来保存str(递归(10000000000000000))
或计算递归(10000000000000000)
。使用对数可以验证所涉及的内存是否过大。您试图计算的函数比任何指数函数都增长得快。谢谢。我试过你的方法,但奇怪的是结果总是1。你知道为什么吗?而且这个计划永远不会结束。它不显示任何输出。@Vincent.N此答案中的代码并不总是返回1。如果这就是你所观察到的——也许检查你的缩进。它“永远”不会结束,因为循环10000000000000000次需要很多时间。在for loop中添加一个简单的打印,看看效果如何。谢谢大家的回答@约翰科勒曼:对不起,我太蠢了。我把I和1搞混了,没注意到。@RafalS我试过了