python:递归检查以确定字符串是不是为回文

Posted

技术标签:

【中文标题】python:递归检查以确定字符串是不是为回文【英文标题】:python: recursive check to determine whether string is a palindromepython:递归检查以确定字符串是否为回文 【发布时间】:2012-07-14 20:20:57 【问题描述】:

我的任务是定义一个过程 is_palindrome,它将一个字符串作为输入,并返回一个布尔值,指示输入字符串是否是回文。在这种情况下,单个字母应返回 True,空字符串 '' 也应返回 True。

很遗憾,我没有得到预期的结果。我很感激帮助。

我的代码版本 1:

def is_palindrome(s):
    if s == '':
        return True
    else:
        if (ord(s[0]) - ord(s[len(s)-1])) == 0:
            is_palindrome(s[1:len(s)-1])
        else:
            return False

print is_palindrome('')
#>>> True    (expected = True)

print is_palindrome('abab')
#>>> False    (expected = False)

print is_palindrome('abba')
#>>> None    (expected = True)

print is_palindrome('andrea')
#>>> None    (expected = False)

print is_palindrome('abaaba')
#>>> None    (expected = True)

我通过调试器跟踪我的代码,看起来逻辑是正确的,因为代码采用了适当的路径。但是,对于上面突出显示的某些情况,最终结果似乎切换为“无”。

如果我将代码更改为以下内容:

我的代码版本 2:

def is_palindrome(s):
        if s == '':
            result = True
        else:
            if (ord(s[0]) - ord(s[len(s)-1])) == 0:
                is_palindrome(s[1:len(s)-1])
            else:
                result = False
        return result

print is_palindrome('')
#>>> True    (expected = True)

print is_palindrome('abab')
#>>> False    (expected = False)

print is_palindrome('abba')
#>>> Error    (expected = True)
UnboundLocalError: local variable 'result' referenced before assignment 

print is_palindrome('andrea')
#>>> Error   (expected = False)         
UnboundLocalError: local variable 'result' referenced before assignment

print is_palindrome('abaaba')
#>>> Error    (expected = True)
UnboundLocalError: local variable 'result' referenced before assignment

【问题讨论】:

在 if 子句中尝试result = is_palindrome(s[1:len(s)-1]) 如果这是作业,请标记它。 这很奇怪:(ord(s[0]) - ord(s[len(s)-1])) == 0s[0] == s[-1] 不行吗? @NedBatchelder - 不,不是家庭作业。在我的生活中,我已经过去了。我只是在玩免费的在线课程来学习。 :) @JoranBeasley:好吧,如果我们这样做,为什么不s == s[::-1]?大概OP有递归要求。 [PS:单字母的情况有效,因为s[0] == s[len(s)-1] == s[1-1] == s[0]。] 【参考方案1】:

在您的第一个示例中,您忘记了返回语句:

def is_palindrome(s):
    if s == '':
        return True
    else:
        if (ord(s[0]) - ord(s[len(s)-1])) == 0:
            # v-- forgot this here
            return is_palindrome(s[1:len(s)-1])
        else:
            return False

【讨论】:

感谢您指出我的疏忽。呸!非常感谢。我还按照 Ned Batchelder 的建议进行了更改。 还要注意许多回答者使用的速记。 s[1:len(s)-1] 更简洁地写成s[1:-1]。我认为这主要对简洁的代码很重要,但如果您更喜欢使用len(),最好在函数开头只调用一次并重用结果。我确信 mVChr 知道所有这些,但由于 OP 对 Python 来说是新的,我认为值得额外注意。 @EMS - 同意您的观点,感谢您提请我注意。我是 python 新手。 :-)【参考方案2】:
        is_palindrome(s[1:len(s)-1])

需要...

        return is_palindrome(s[1:len(s)-1])

在您的第一个版本中,或

        result = is_palindrome(s[1:len(s)-1])

在你的第二个。否则,您永远不会真正将递归调用的返回值传播回原始调用者。

【讨论】:

【参考方案3】:
# ask user to enter any string
a = raw_input("Enter the string : ")
#palindrome check
print (a == a[::-1]) and "String is palindrome" or "String is not palindrome"

【讨论】:

【参考方案4】:

让我们逐行执行第二个示例。

def is_palindrome(s):

在这种情况下,让我们让 s = "abba",这是您遇到错误的第一个字符串:

        if s == '':

被评估为

        if 'abba' == '':

这是False,所以我们跳到else

        else:
            if (ord(s[0]) - ord(s[len(s)-1])) == 0:

这个if 语句相当于:

            if (97 - 97) == 0:

它是True,所以递归发生了:

                is_palindrome(s[1:len(s)-1])

                is_palindrome('bb')

现在无论这个递归的结果是什么,我们都忽略它,因为返回值没有被保存。因此,当我们到达这一行时:

        return result

我们从来没有定义过result 是什么,所以 Python 被淘汰了。

其他海报已经很好地回答了您的问题。我发帖是为了证明跟踪程序以查找/修复错误的重要性。

【讨论】:

Joel 非常感谢您对跟踪我的函数的演示。在我写作和学习的过程中,我会将其融入到我的实践中。【参考方案5】:
def is_palindrome(s):
    if not s:
        return True
    else:
        return s[0]==s[-1] and is_palindrome(s[1:-1])

或者,如果您想要单线:

def is_palindrome(s):
    return (not s) or (s[0]==s[-1] and is_palindrome(s[1:-1]))

希望有帮助

【讨论】:

任何人都可以解释为什么当输入是单个字符时 Python 索引应该在单行中正确工作的直觉?我已经对其进行了测试,它确实有效,但是'a'[1:-1] 返回空字符串的想法很奇怪。如果'a'[1] 给出错误,那么'a'[1:-1] 不应该也给出错误吗?对我来说,这似乎是 unPythonic。似乎list[K:-1] 为任何K > len(list) 回馈''。奇怪的;我想我更喜欢索引错误。 @EMS:这是因为尽管索引 1 不存在,但 'a'[1:] /is/ 为空,正如预期的那样。对于L=[1,2,3,4]L[7:] 就是[],这很直观。这能解释一些事情吗? 但是按照同样的逻辑,L[7](或者L[7:8],如果你愿意的话)也只是空列表(空列表的任何子集都是空列表),所以不,这确实看起来一点也不直观(因为L[7] 会出错)。为什么L[7:8]是空列表,而L[7]是错误? 我想我更多是从 C 风格的角度来看的。我期望像L[i] 指向内存中的某个位置并获得L 居住在那里的元素之类的东西。 L[i:j] 只是持有L[i] 的内存点的简写......直到L[j-1]。如果它试图获取L[i] 并且没有与L 关联的这样的内存点,那么它应该停在那里。空字符毕竟还是字符。 如果我没有分配任何东西来发现 Li,那么 Python 编造一些东西似乎不太好,因为我要求的是一系列对象而不是一个单个对象。 Python 有一些很好的语法约定,但是对于像列表这样的数据结构,这似乎是矛盾的。如果L[i] 不是一件事,那么L[i:-1] 肯定也不是一件事,如果一个人出错,另一个人也应该出错。当然是我的两分钱。比我聪明的人创造了 Python,所以我相信他们有他们的理由。【参考方案6】:

Java 的回答

public class Varios 

/**
 * @param args the command line arguments
 */
  public static void main(String[] args) 
    System.out.println( pali("anitalavalatina"));
  
  static boolean pali(String palabra)
    System.out.println(palabra);
    if (palabra.length()-1<2) 
            return true;
    if(palabra.charAt(0)!=palabra.charAt(palabra.length()-1)) return false;
    return pali(palabra.substring(1,palabra.length()-1));
  


【讨论】:

以上是关于python:递归检查以确定字符串是不是为回文的主要内容,如果未能解决你的问题,请参考以下文章

检查字符串是不是是回文的字谜

用递归判断字符串是不是为回文串(C语言) 用递归判断字符串是不是为回文串(C语言)

用递归方法判断字符串是否是回文(Recursion Palindrome Python)

使用 Deque 检查给定字符串是不是为回文

如何检查字符串是不是以回文开头?

C语言:编写一个测试一个串是不是为回文的递归函数,是回文,返回1;不是,返回0。