打破递归函数?

时间:2012-05-11 02:09:45

标签: python

我想知道如何打破主函数的递归循环。我正在尝试做一个简单的回文练习。该函数应为“redivider”返回True,但返回True将传递给is_pal()并且函数不会中断。如果没有向is_pal添加第二个变量来跟踪True / False,那么打破这个递归循环的正确方法是什么?感谢。

def first(word):
    return word[0]

def last(word):
    return word[-1]

def middle(word):
    return word[1:-1]

def is_pal(str):    
    if len(str) == 1: 
        return True

    if first(str) == last(str) and len(str) > 1: 
        is_pal(middle(str))

print is_pal("redivider")

7 个答案:

答案 0 :(得分:7)

def is_pal(str):    
    if len(str) <= 1: 
        return True

    if first(str) == last(str): 
        return is_pal(middle(str))
    else:
        return False

这样,如果它们不匹配,则返回False;如果它一直到最后,True返回。我还消除了冗余条件并检查了偶数长度回文的边缘情况。

答案 1 :(得分:7)

你不会“破坏”递归函数。试图这样做说你正在以错误的方式思考它们。目前你的递归调用忽略了输出,这意味着递归是没有意义的;无论is_pal(middle(str))返回什么都不会影响函数的返回值。

递归算法通过将问题分解为较小的问题,递归地解决较小的问题,然后使用较小的解决方案为较大的问题构建正确的解决方案来解决输入问题。你没有“打破”内部调用,你返回一个级别的解决方案。您不知道(或需要知道)需要知道您是在内线电话还是顶级电话。在任何一种情况下,你的函数应该做同样的事情:如果参数是回文,则返回True,如果不是,则返回False。

您尝试实施的算法基本上是这样的:

  1. 如果字符串长度为1,则为回文(返回True)
  2. 否则,如果第一个字符与最后一个字符相同,那么如果中间字符是回文,则输入是回文。
  3. 所以这意味着,一旦你确定了第一个和最后一个字符是相同的,“我的输入是一个回文”的答案是完全相同作为答案“是中间人物是一个回文“。您需要返回该答案才能履行合同。因此,递归调用应该是return is_pal(middle(str)),而不仅仅是is_pal(middle(str))。如果这是一个顶级电话,那就是答案;如果不是一个顶级调用,那么外部调用将需要这个答案来解决外部问题的答案(在这种情况下,只需返回它)。


    不过,您的算法还有其他一些问题。

    1. 你永远不会返回False,所以答案永远不会是False(在这种情况下,如果第一个和最后一个,你会偶然地通过从函数末尾掉落None而意外返回None字符不匹配,False在大多数情况下可能会代表{{1}},但它仍然不是正确的)。
    2. 如果字符串的长度是而不是1(如果在中传入一个空字符串,如果偶数长度的回文传入一次,则会发生这种情况剥离了相同的第一个和最后一个字符对,然后你没有返回正确的答案,实际上你试图得到空字符串的第一个和最后一个字符,这将导致异常。

答案 2 :(得分:3)

在Python中打破递归函数的一种方法是抛出异常并在顶层捕获它。有些人会说这不是考虑递归的正确方法,但它可以完成工作。此外,如果任务是识别数组/数组/ ndarray等数组/数组中的“问题”元素,则中断技术很方便,因为它在确定正确的全局解决方案后停止算法继续。

def solve_problem(lst):
    def solve_rec(l):
        '''has impl. that may throw an exception '''
    try:
        solve_rec(lst)
        return True
    except:
        return False

答案 3 :(得分:1)

您需要返回递归调用的结果,如果未采取其他路径,则还需要添加return False

def is_pal(str):    
    if len(str) == 1: 
        return True

    if first(str) == last(str) and len(str) > 1: 
        return is_pal(middle(str))

    return False

答案 4 :(得分:0)

你错过了回归。另外,请勿使用str作为变量名。最后,第一个和最后一个函数可以稍微好一点命名。

def first_letter(word):
    return word[0]

def last_letter(word):
    return word[-1]

def middle(word):
    return word[1:-1]

def is_pal(word):    
    if len(word) == 1: 
        return True

    if first_letter(word) == last_letter(word) and len(word) > 1:
        return is_pal(middle(word))

print is_pal("redivider")

答案 5 :(得分:0)

如果它们不匹配,则需要返回False并添加return语句。您也可能想要检查len(str)== 0和len(str)== 1:

def is_pal(str):
    if len(str) in [0, 1]:
        return True
    if first(str) == last(str) and len(str) > 1:
        return is_pal(middle(str))
    else :
        return False

答案 6 :(得分:0)

使用exit()功能打印结果后,可以退出程序。

这可能不是一个好习惯,但这可能正是您想要的。