Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.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_Python 3.x_Recursion_Python Idle_Tail Recursion - Fatal编程技术网

Python 使递归函数迭代?

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

当我运行下面的模块时,它运行大约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':
            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猜想后,在“最外层”函数中永远循环是有意义的,但递归地循环是没有意义的

我认为这是因为你混淆了这个计划的两个不同部分:

  • 你要检查每个自然数的Collatz猜想
  • 您需要计算Collatz序列
  • 让我们解决第一个问题,因为它更容易。要检查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