这个函数是递归的,即使它不';你不叫自己吗? 从pythonds.basic.stack导入堆栈 rStack=Stack() def toStr(北,基准): convertString=“0123456789ABCDEF” 当n>0时: 如果n

这个函数是递归的,即使它不';你不叫自己吗? 从pythonds.basic.stack导入堆栈 rStack=Stack() def toStr(北,基准): convertString=“0123456789ABCDEF” 当n>0时: 如果n,python,recursion,Python,Recursion,我指的是上面的代码,也粘贴了上面的代码。教程说这个函数是递归的,但我没有看到任何递归调用,只是一个while循环。我缺少什么?因为您使用的是堆栈结构 如果你考虑函数调用是如何实现的,递归本质上是让编译器为你管理一堆调用的简单方法。 此函数手动执行所有堆栈处理,但在概念上它仍然是一个递归函数,只是其中堆栈管理是手动执行的,而不是让编译器执行。您是对的,此特定函数不是递归的。然而,上下文是,在上一张幻灯片上有一个递归函数,在这张幻灯片中,他们想展示一下它在内部的行为。他们后来说: 前面的示例[即有问

我指的是上面的代码,也粘贴了上面的代码。教程说这个函数是递归的,但我没有看到任何递归调用,只是一个while循环。我缺少什么?

因为您使用的是堆栈结构

如果你考虑函数调用是如何实现的,递归本质上是让编译器为你管理一堆调用的简单方法。


此函数手动执行所有堆栈处理,但在概念上它仍然是一个递归函数,只是其中堆栈管理是手动执行的,而不是让编译器执行。

您是对的,此特定函数不是递归的。然而,上下文是,在上一张幻灯片上有一个递归函数,在这张幻灯片中,他们想展示一下它在内部的行为。他们后来说:

前面的示例[即有问题的-B.]让我们对Python如何实现递归函数调用有了一些了解

所以,是的,标题是误导性的,它应该是扩展递归函数,或者用堆栈或类似的东西来模仿递归函数的行为

有人可能会说,在某种意义上,该函数对要解决的问题采用了递归方法/策略,但它本身不是递归的。

根据定义,它是一种递归算法

这里的问题是将一个数字转换为给定符号中的字符串

函数的“存储”数据实际上如下所示:

from pythonds.basic.stack import Stack

rStack = Stack()

def toStr(n,base):
    convertString = "0123456789ABCDEF"
    while n > 0:
        if n < base:
            rStack.push(convertString[n])
        else:
            rStack.push(convertString[n % base])
        n = n // base
    res = ""
    while not rStack.isEmpty():
        res = res + str(rStack.pop())
    return res

print(toStr(1345,2))
这实际上是:

push(d1)
push(d2)
...
push(dn-1)
push(dn)

res+=pop(dn)
res+=pop(dn-1)
...
res+=pop(d2)
res+=pop(d1)
即,处理特定数据块的步骤包含处理其余数据的所有步骤(每个数据块的处理方式相同)

如果函数是递归的(因为它们倾向于在狭义上将该术语应用于子例程),则可能会有争议,但它实现的算法肯定是递归的


为了让您更好地感受到差异,这里有一个相同问题的迭代解决方案:

def pushpop():
    push(dx)
    pushpop(dx+1...dn)
    res+=pop(dx)

如您所见,此方法的内存占用要小得多,因为它不存储任务。这就是区别:迭代算法使用状态的同一实例执行每一步,方法是对其进行变异,而递归算法则为每一步创建一个新实例,如果仍然需要旧实例,则必须将它们存储起来。

使用堆栈不会使函数递归。堆栈只是大多数(如果不是所有)语言用来处理嵌套函数调用的数据结构,递归调用只是其中的一种类型。我不会马上否定这个答案。根据递归的定义,它是“涉及对连续结果重复应用规则、定义或过程”。它没有提到需要调用自己来被视为递归。堆栈结构似乎是帮助概念化递归概念的好方法,而无需函数本身调用。我错了吗?@kalin,堆栈结构是递归的实际实现方式——看看调用堆栈(递归依赖于调用堆栈)是如何实现的。因此,这不仅仅是一个有用的概念,也是真实事物的实现方式。@kalin这不是“递归”的一个很好的定义,那么,因为该定义可以很容易地应用于“迭代”,并且无法捕捉“递归”所暗示的“自引用”的通常概念…@kalin,好吧,反对意见是正确的,在某种程度上,使用堆栈(或等价物)对于常规递归函数实现是必要的,但还不够。这是一个平衡的行动,就反对是否使这成为一个糟糕的答案而言;我个人认为不是。也就是说,我同意反对意见(仅限于)采用“递归”的定义,允许不调用自己的函数被视为显式递归,而不是递归的说明,我的天啊,这篇教程的作者有没有听过PEP-8?@I有什么问题吗?代码可读性很强。C/C++可以做到这一点(可能还有其他一些),Python可以做到这一点。更具可读性。BDFL命令它,所以我们必须遵守:-)。用实现TCO的语言编写的尾部递归函数是否不再递归?毕竟,它的足迹不再与深度成正比。TCO只是内部优化。展开的循环仍然是循环吗?不管怎样,你有没有看到其他方法来区分迭代和递归?作为一个在Haskell附近呆了一段时间的人,我很想把函数看作纯粹的数学构造,将其定义的属性与任何相关运行时实现的属性分离。我想我已经做到了——这就是区别的方式。
def toStr(n,base):
    charmap = "0123456789ABCDEF"
    res=''
    while n > 0:
        res = charmap[n % base] + res
        n = n // base
    return res