【问题标题】: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]。]

标签: python string recursion


【解决方案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));
        }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-02
        • 2012-04-05
        • 2022-11-15
        相关资源
        最近更新 更多