Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中已超过最大递归深度_Python_Function_Recursion - Fatal编程技术网

python中已超过最大递归深度

python中已超过最大递归深度,python,function,recursion,Python,Function,Recursion,我正试图通过递归来构造幂函数。 但我得到了运行时错误,比如超过了最大递归深度。 我将感谢任何帮助!! 这是我的密码 def fast_power(a,n): if(n==0): return 1 else: if(n%2==0): return fast_power(fast_power(a,n/2),2) else: return fast_power(fast_power(a,n/2),

我正试图通过递归来构造幂函数。 但我得到了运行时错误,比如超过了最大递归深度。 我将感谢任何帮助!! 这是我的密码

 def fast_power(a,n):
    if(n==0):
        return 1
    else:
       if(n%2==0):
           return fast_power(fast_power(a,n/2),2)
       else:
           return fast_power(fast_power(a,n/2),2)*a

您应该使用
n//2
而不是
n/2

>>> 5 // 2
2
>>> 5 / 2
2.5
(至少在蟒蛇3中)

问题是,一旦以浮点结束,则需要相当长的时间才能除以
2以
0
结束:

>>> 5 // 2
2
>>> 5 / 2
2.5
>>> from itertools import count
>>> n = 5
>>> for i in count():
...     n /= 2
...     if n == 0:
...         break
... 
>>> i
1076
因此,正如您所看到的,要从
5
到达
0
,您需要1000多个递归调用,这超过了默认的递归限制。除此之外:该算法是用来运行整数的


这意味着我将把该函数写成如下形式:

def fast_power(a, n):
    if n == 0:
        return 1
    tmp = fast_power(a, n//2)
    tmp *= tmp
    return a*tmp if n%2 else tmp
产生:

>>> fast_power(2, 7)
128
>>> fast_power(3, 7)
2187
>>> fast_power(13, 793)
22755080661651301134628922146701289018723006552429644877562239367125245900453849234455323305726135714456994505688015462580473825073733493280791059868764599730367896428134533515091867511617127882942739592792838327544860344501784014930389049910558877662640122357152582905314163703803827192606896583114428235695115603966134132126414026659477774724471137498587452807465366378927445362356200526278861707511302663034996964296170951925219431414726359869227380059895627848341129113432175217372073248096983111394024987891966713095153672274972773169033889294808595643958156933979639791684384157282173718024930353085371267915606772545626201802945545406048262062221518066352534122215300640672237064641040065334712571485001684857748001990405649808379706945473443683240715198330842716984731885709953720968428395490414067791229792734370523603401019458798402338043728152982948501103056283713360751853

您应该使用
n//2
而不是
n/2

>>> 5 // 2
2
>>> 5 / 2
2.5
(至少在蟒蛇3中)

问题是,一旦以浮点结束,则需要相当长的时间才能除以
2以
0
结束:

>>> 5 // 2
2
>>> 5 / 2
2.5
>>> from itertools import count
>>> n = 5
>>> for i in count():
...     n /= 2
...     if n == 0:
...         break
... 
>>> i
1076
因此,正如您所看到的,要从
5
到达
0
,您需要1000多个递归调用,这超过了默认的递归限制。除此之外:该算法是用来运行整数的


这意味着我将把该函数写成如下形式:

def fast_power(a, n):
    if n == 0:
        return 1
    tmp = fast_power(a, n//2)
    tmp *= tmp
    return a*tmp if n%2 else tmp
产生:

>>> fast_power(2, 7)
128
>>> fast_power(3, 7)
2187
>>> fast_power(13, 793)
22755080661651301134628922146701289018723006552429644877562239367125245900453849234455323305726135714456994505688015462580473825073733493280791059868764599730367896428134533515091867511617127882942739592792838327544860344501784014930389049910558877662640122357152582905314163703803827192606896583114428235695115603966134132126414026659477774724471137498587452807465366378927445362356200526278861707511302663034996964296170951925219431414726359869227380059895627848341129113432175217372073248096983111394024987891966713095153672274972773169033889294808595643958156933979639791684384157282173718024930353085371267915606772545626201802945545406048262062221518066352534122215300640672237064641040065334712571485001684857748001990405649808379706945473443683240715198330842716984731885709953720968428395490414067791229792734370523603401019458798402338043728152982948501103056283713360751853

我相信@Bakuriu对这个问题的解释是不完整的。不是他的重新实现,而是他对你的bug的解释。您可以通过将原始代码中的
/
替换为
/
来说服自己,然后尝试:

fast_power(2, 2)
它仍然超出堆栈。尝试将堆栈扩展十倍:

sys.setrecursionlimit(10000)
它仍然超出堆栈。原因是您还有一个infinte循环:

if (n % 2 == 0):
    return fast_power(..., 2)
由于2%2==0,这将永远保持递归。添加另一个基本情况:

if n == 2:
    return a * a
解决了这个问题。完整的解决方案:

def fast_power(a, n):
    if n == 0:
        return 1

#   if n == 1:
#       return a

    if n == 2:
        return a * a

    if n % 2 == 0:
        return fast_power(fast_power(a, n // 2), 2)

    return a * fast_power(fast_power(a, n // 2), 2)

我相信@Bakuriu对这个问题的解释是不完整的。不是他的重新实现,而是他对你的bug的解释。您可以通过将原始代码中的
/
替换为
/
来说服自己,然后尝试:

fast_power(2, 2)
它仍然超出堆栈。尝试将堆栈扩展十倍:

sys.setrecursionlimit(10000)
它仍然超出堆栈。原因是您还有一个infinte循环:

if (n % 2 == 0):
    return fast_power(..., 2)
由于2%2==0,这将永远保持递归。添加另一个基本情况:

if n == 2:
    return a * a
解决了这个问题。完整的解决方案:

def fast_power(a, n):
    if n == 0:
        return 1

#   if n == 1:
#       return a

    if n == 2:
        return a * a

    if n % 2 == 0:
        return fast_power(fast_power(a, n // 2), 2)

    return a * fast_power(fast_power(a, n // 2), 2)

这就是为什么在非纯函数语言中使用递归通常是一个坏主意,除非你确定它不会运行很长时间。每次调用同一个函数一次,你就调用两次。这将在运行时爆炸并占用指数内存。你确定算法正确吗?@Carcigenicate算法正确。它使用的事实是
x^2n==(x^n)^2
。然而,
^2
可以用乘法代替:
x=fast\u幂(a,n//2);返回x*x
@Carcigenicate在任何情况下,导致递归超出错误的问题是使用
/
进行除法,如我的答案所示。算法应该只使用整数,因此应该使用整数除法
/
,而不是
/
@Bakuriu OK。我不知道算法,所以这就是我最突出的地方。这就是为什么在非纯函数语言中使用递归通常是个坏主意,除非你确定它不会运行很长时间。每次调用同一个函数一次,你都要调用两次。这将在运行时爆炸并占用指数内存。你确定算法正确吗?@Carcigenicate算法正确。它使用的事实是
x^2n==(x^n)^2
。然而,
^2
可以用乘法代替:
x=fast\u幂(a,n//2);返回x*x
@Carcigenicate在任何情况下,导致递归超出错误的问题是使用
/
进行除法,如我的答案所示。算法应该只使用整数,因此应该使用整数除法
/
,而不是
/
@Bakuriu OK。我不知道算法,所以这才是我最喜欢的。