Python 使递归函数迭代?
当我运行下面的模块时,它运行大约960个递归:Python 使递归函数迭代?,python,python-3.x,recursion,python-idle,tail-recursion,Python,Python 3.x,Recursion,Python Idle,Tail Recursion,当我运行下面的模块时,它运行大约960个递归: import matplotlib import pylab xStart = 1 debug = 'off' xList = [] calcList = [] def collatzCalc(xStart,calcs): calc = 0 xCalc = 0 xCalc = xStart while xCalc > 0: if debug == 'on': prin
import matplotlib
import pylab
xStart = 1
debug = 'off'
xList = []
calcList = []
def collatzCalc(xStart,calcs):
calc = 0
xCalc = 0
xCalc = xStart
while xCalc > 0:
if debug == 'on':
print(round(xCalc))
print(xList)
print(calcList)
if xCalc == 1:
xList.append(xStart)
calcList.append(calc)
xStart += 1
if debug == 'on':
print(calcs)
print('---------------------------')
calcs += 1
collatzCalc(xStart,calcs)
else:
if xCalc % 2 == 0:
xCalc = xCalc / 2
calc += 1
else:
xCalc = xCalc * 3 + 1
calc += 1
calcs = 0
collatzCalc(xStart,calcs)
它抛出以下错误:
Traceback (most recent call last):
File "C:\Users\Erin Lynch\Desktop\collatzConjecture.py", line 49, in <module>
collatzCalc(xStart,calcs)
File "C:\Users\Erin Lynch\Desktop\collatzConjecture.py", line 32, in collatzCalc
collatzCalc(xStart,calcs)
File "C:\Users\Erin Lynch\Desktop\collatzConjecture.py", line 14, in collatzCalc
while xCalc > 0:
RuntimeError: maximum recursion depth exceeded in comparison
回溯(最近一次呼叫最后一次):
文件“C:\Users\Erin Lynch\Desktop\CollatzConsculation.py”,第49行,在
collatzCalc(xStart,calcs)
collatzCalc中的第32行文件“C:\Users\Erin Lynch\Desktop\CollatzConsculation.py”
collatzCalc(xStart,calcs)
collatzCalc中第14行的文件“C:\Users\Erin Lynch\Desktop\CollatzConsculation.py”
当xCalc>0时:
RuntimeError:比较中超出了最大递归深度
我知道为什么会发生这种情况,因为我今天读了关于递归限制的书,但我想知道的是如何将递归公式转化为迭代公式。我完全不知道怎么做,我需要知道怎么做的人的帮助 首先,在本部分中,第一行是不必要的,因为
xCalc
将立即被xStart
覆盖:
xCalc = 0
xCalc = xStart
其次,如果仔细观察代码,您会发现如果xCalc
曾经到达1
它将永远循环:
def collatzCalc(xStart,calcs):
...
xCalc = xStart
while xCalc > 0:
...
if xCalc == 1:
...
collatzCalc(xStart,calcs)
else:
...
由于xCalc
是一个局部变量,因此collatzCalc
的其他实例无法修改此变量。该函数将永远保持循环。虽然在检查Collatz猜想后,在“最外层”函数中永远循环是有意义的,但递归地循环是没有意义的
我认为这是因为你混淆了这个计划的两个不同部分:
def checkCollatz(xStart=1, debug=False):
xList = []
calcList = []
while True:
calc = collatzCalc(xStart, debug=debug)
xList.append(xStart)
calcList.append(calc)
if debug:
print(xStart - 1)
print('---------------------------')
xStart += 1
在这里,我将全局变量(xList
,calcList
,xStart
,和debug
)转换为这个最外层函数的局部变量。(您可能还想为它们选择更多描述性名称。)请注意,我已经完全消除了calcs
变量,因为它似乎与xStart
相同,只是总是低一
现在,为了计算Collatz序列,我可以重用您已经拥有的(去掉checkCollatz
中使用的部分):
由于Collatz序列始终是整数,因此不需要使用舍入
。此外,应该使用整数除法(/
)而不是浮点除法(/
),因为/
会将数字强制转换为浮点数字
请注意,这段代码中根本没有递归。递归已被消除并转换为checkCollatz
中的循环(请注意,现在有两个而不是一个循环)。您的原始代码已经基本上是迭代的,所以将其转换为递归代码并不十分复杂
作为旁注,请注意,通过将函数拆分为两个单独的函数,现在变量更少,代码更易于阅读。您确定这是正确的代码吗?我在任何地方都找不到“calcs”,除了:calcs+=1(当然忽略调试打印语句)哦,对不起。意外地取出了一小部分。现在修好它!如果xCalc==1
,那么函数将陷入无限循环,因为该子句中的任何内容都不会改变xCalc
的值,因此它将永远停留在xCalc==1
。发生的是collatzCalc(xStart,calcs)
使它返回到collatzCalc()
函数,下面是xCalc=0
xCalc
是一个局部变量。在子函数中对其所做的操作不会影响父函数。父函数仍将永远循环。
def collatzCalc(xCalc, debug=False):
calc = 0
while xCalc > 0:
if debug:
print(xCalc)
if xCalc == 1:
return calc
else:
if xCalc % 2 == 0:
xCalc = xCalc // 2
else:
xCalc = xCalc * 3 + 1
calc += 1