-2

所以基本上一个人帮助我改进了我的代码。问题是,它仍然非常令人失望并且不起作用。我想做的是重置 lenRecur.number 以便我可以再次使用该函数,使用其他字符串并获得正确答案(不是太大的答案)

我想,问题出在 hasattr 上。但我不能删除它,因为如果我这样做了,我的字符串长度计算器将无法工作。

无论如何,即使我在函数后添加 lenRecur.number = 0 ,它仍然不起作用。

这似乎是不可能的,因为当函数点击“返回”时,它就完成了,句号。如果我在“返回”之前重置它,它将返回 0,而不是正确的答案,所以是的,我在这里遇到了很大的麻烦。

def lenRecur(aStr):
    if not hasattr(lenRecur, 'number'):
        lenRecur.number = 0
    '''
    aStr: a string

    returns: int, the length of aStr
    '''
    if aStr == '':
        return lenRecur.number
    else:
        lenRecur.number += 1
        return lenRecur(aStr[:-1])

Ps 我的程序(?)/脚本(?)的目标是测量输入字符串的长度,而不使用 input() 方法。尝试使用更原始的方法重新创建 length() 方法。

脚本必须有许多不同的输入,所以它应该重置。

4

3 回答 3

3

如果您只想要一个递归强度长度函数,那很容易:

def len_recur(a_str):
    if not a_str:
        return 0
    else:
        return 1 + len_recur(a_str[1:])

当然这不是尾递归,但是 Python 无论如何都不会优化尾递归,所以没关系。

如果你只是为了它而希望它是尾递归的——或者因为你已经阅读了 Paul Butler 的Python 中尾递归的技巧并想尝试一下——你仍然不想通过存储累加器来做到这一点作为函数的属性。只需使用定义本地函数的常用技巧(或使用可变默认参数,如果您愿意):

def len_tail_recur(a_str):
    def tail(a_str, acc):
        if not a_str:
            return acc
        else:
            return tail(a_str[1:], acc+1)
    return tail(a_str, 0)

如果你想把它转换成一个真正的尾递归函数,这样它就不会轰炸 1001 个元素的列表,并且不理解上面的 Paul Butler 链接,请参阅我对Get length of list in Python using recursion 的回答,其中正好解决了这个问题。(该问题的另一个答案还显示了如何使用 log N 递归调用而不是 N 来解决问题,这是解决问题的另一种方法,除非你有不可能的 long lists。)

话虽如此,即使您的实现方式是错误的,但它实际上工作得很好。(到目前为止,我一直在对您的代码进行 PEP8 化,使其看起来更像惯用的 Python;从这里开始,我将按原样复制粘贴,但您的真实代码应该类似于上面的代码。)

def lenRecur(aStr):
    if not hasattr(lenRecur, 'number'):
        lenRecur.number = 0
    '''
    aStr: a string

    returns: int, the length of aStr
    '''
    if aStr == '':
        return lenRecur.number
    else:
        lenRecur.number += 1
        return lenRecur(aStr[:-1])

print lenRecur('abc')
lenRecur.number = 0
print lenRecur('abcd')

这打印3,然后4。当然,您必须lenRecur.number从函数外部进行设置,因为在函数内部您仍然需要该值。但是你可以用同一种包装器来解决这个问题:

def lenRecur(aStr):
    lenRecur.number = 0
    '''
    aStr: a string

    returns: int, the length of aStr
    '''
    def recur(aStr):
        if aStr == '':
            return lenRecur.number
        else:
            lenRecur.number += 1
            return recur(aStr[:-1])
    return recur(aStr)
于 2013-01-17T00:39:30.993 回答
2

您不必在函数内使用状态变量。如果你想制作一个递归长度计算器,那么就做

def lenRecur (aStr):
    if (aStr == ""):
        return 0
    else
        return lenRecur (aStr [:-1]) + 1

另请注意,这种风格没有错误检查等,但出于学习递归的目的,它可以正常工作。

于 2013-01-17T00:39:00.837 回答
1

如果您试图通过使用递归实现长度函数来理解递归,那么您可以使用如下内容:

#!python
def lenRecur(something, curlen=0):
    if something:
        return lenRecur(something[1:], curlen+1)
    else:
        return curlen

...我不会声称这是特别好的代码。但它应该适用于任何类型的序列(字符串、列表、元组)......只要 [1:] 切片操作不超过正在运行的 Python 实例中的最大递归限制,它就可以工作。

在您的示例中,您试图通过使用 hasattr 来实现类似的概念,以“猴子补丁”具有“数字”属性的函数对象。在我的示例中,我使用默认参数作为将变量向下传递到递归调用的一种方式。

所以在初始调用中 curlen 为零(使用“可选”额外参数调用它会产生虚假结果)。从该调用中,该函数使用原始序列(字符串)的一部分来调用自身,该序列从头部切掉(使其更短),并且可选的(curlen)参数递增。最后,字符串/序列的长度为零,通过之前的每个(递归)调用返回零。

这是实现这一点的一种蹩脚的方式,它可能是讨论尾递归消除的起点(谷歌)。但它可以在没有猴子修补你的函数/对象的情况下工作。

于 2013-01-17T00:56:36.077 回答