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

python:递归检查以确定字符串是否为回文,python,string,recursion,Python,String,Recursion,我的任务是定义一个过程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,它接受一个字符串作为输入,并返回一个布尔值,指示输入字符串是否为回文。在这种情况下,单个字母应返回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
需要

        return is_palindrome(s[1:len(s)-1])
在您的第一个版本中,或者

        result = is_palindrome(s[1:len(s)-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
或者,如果您想要一行:

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

希望这能有所帮助

让我们逐行浏览第二个示例:

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:
它是
真的
,因此递归发生:

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

现在不管这个递归的结果是什么,我们忽略它,因为返回值没有保存。因此,当我们到达这条线时:

        return result
我们从未定义什么是
result
,因此Python被抛出

其他的海报已经很好地回答了你的问题。我发帖是为了演示跟踪程序以发现/修复bug的重要性。

Respuesta en Java

# 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"
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));
  }

}
公共类Varios{
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
System.out.println(巴利语(“Anitalavatina”);
}
静态布尔巴利语(字符串帕拉布拉语){
系统输出打印(palabra);

如果(palabra.length()-1try
result=is_回文(s[1:len(s)-1])
在if子句中如果这是作业,请将其标记为这样。这很奇怪:
(ord(s[0])-ord(s[len s)-1])==0
。不会
s[0]==s[-1]
work?@NedBatchelder-不,不是家庭作业。我的生活已经不再是这样了。我只是在玩免费的在线课程来学习。@JoranBeasley:好吧,如果我们这样做,为什么不
s==s[:::-1]
?大概OP有递归的要求。[PS:单字母大小写是可行的,因为
s[0]==s[len(s)-1]=s[1-1]==s[0]
]谢谢你指出我的疏忽。Duh!非常感谢。我也按照Ned Batchelder的建议进行了更改。还要注意许多回答者使用的速记。
s[1:len(s)-1]
更简洁地写为
s[1:-1]
。我认为这主要关系到简洁的代码,但如果您更喜欢使用
len()
,最好在函数开始时只调用它一次并重用结果。我相信mVChr知道所有这些,但由于OP对Python来说是新的,所以我认为值得多加注意。@EMS-同意你的观点,并感谢你提醒我这一点。我是Python新手。:-)有人能解释一下为什么Pyt的直觉吗当输入是单个字符时,hon索引应该在一行中正确工作?我已经测试过了,它确实工作,但是
'a'[1:-1]
返回空字符串的想法很奇怪。如果
'a'[1]
给出错误,那么就不应该
'a'[1:-1]
也给出一个错误?这对我来说似乎是不和谐的。似乎
list[K:-1]
为任何
K>len(list)
返回
。奇怪;我想我更喜欢索引错误。@EMS:这是因为尽管索引1不存在,
'a'[1:][/code>/正如预期的那样是/空的。对于
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
相关的内存点,那么它应该就停在那里。空字符毕竟仍然是一个字符。如果我没有为
L
的spot
I
分配任何内容,那么Python就不会因为我要求运行一个对象而仅仅是一个si而编造一些东西Python有一些很好的语法约定,但是对于像列表这样的数据结构来说,这似乎是矛盾的。如果
L[i]
不是一件事,那么肯定
L[i:-1]
也不是一回事,如果一个给出错误,另一个也应该如此。当然,我的两分钱。比我更聪明的头脑制作了Python,所以我相信他们有自己的理由。Joel非常感谢您演示跟踪我的函数。我将在编写和学习时将其纳入实践。
        return result
# 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"
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));
  }

}