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])) == 0
。 s[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
关联的这样的内存点,那么它应该停在那里。空字符毕竟还是字符。
如果我没有分配任何东西来发现 L
的 i
,那么 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语言)