【问题标题】:Palindrome check with recursive function without slicing and loops使用递归函数进行回文检查,无需切片和循环
【发布时间】:2018-12-11 17:16:20
【问题描述】:

我有一个任务,我必须编写一个 python 代码,使用返回布尔值的递归函数来检查字符串是否为回文,但我不允许使用反向切片或循环,也不允许我使用更改函数格式,这是我的代码,但它始终返回 True

def is_palindrome(s):
    res = []
    s = ['']
    if len(s) < 2:
        return True
    else:
        rev_s = is_palindrome(s[1:]) + s[0]
        res.append(rev_s)
        if res == s:
            return True
        return False

【问题讨论】:

  • 您将函数第二行的s 重新分配给['']。它的长度总是小于2,所以你总是会返回True。我想你不想要那条线:s = ['']。
  • 格式错误 - 您的身份已关闭。请修复。
  • 你在这里使用了切片:is_palindrome(s[1:]).
  • @Thaa'er,同样的函数签名with 1 pparameter也可以实现你的目标。这个概念是在第二次递归调用中改变参数(to list)。我已将代码粘贴到我的答案中,请检查。

标签: python python-2.7 recursion palindrome


【解决方案1】:

你可以检查给定字符串的第一个和最后一个字符是否相同,然后递归检查剩余的字符串是否是回文:

def is_palindrome(s):
    return len(s) < 2 or s[0] == s[-1] and is_palindrome(s[1:-1])

【讨论】:

  • @PatrickArtner 我相信 OP 说只允许反向切片。
  • s[-1] 不是倒过来了吗?
  • 啊,所以没有k == k[::-1]?
  • @jimfawkes 不,反向切片是指使用切片构造函数的第三个参数,例如s[::-1].
  • @jimfawkes 这只是取最后一个字符
【解决方案2】:

我不确定这是否算作“更改函数格式”,但这是我对没有切片的递归版本的尝试:

def is_palindrome(s):
  def is_palindrome_r(i, j):
    if j <= i:
      return True
    if s[i] != s[j]:
      return False
    return is_palindrome_r(i + 1, j - 1)

  return is_palindrome_r(0, len(s) - 1)

内部函数is_palindrome_r 是一个递归函数,它采用两个索引i 和j。最后一行将这两个索引的初始位置设置为0(字符串的开头)和len(s) - 1(字符串的结尾)并继续执行递归逻辑。递归函数有两个退出条件:

  1. 如果j &lt;= i 我们已经到达回文的中心。如果我们已经走到这一步,我们知道所有其他字符对都匹配,我们不需要再做任何比较。
  2. 如果i和j指向的两个字符不匹配,那肯定不是回文,我们不需要再做比较了。

否则我们还不知道序列是否完全回文,因此我们将索引向内移动一步 (i + 1, j - 1) 并返回到第 1 步。

【讨论】:

  • 您的代码是正确的,并且符合我的问题中的所有条件,但是您能否详细解释一下您在最后两行中所做的事情?
  • @Thaa'erSawaid 我在上面提供了更全面的解释。
【解决方案3】:

不使用切片,只需通过递归调用维护索引

def is_palindrome(s):
  return helper(s, 0, len(s)-1)

def helper(s, i, j):
  if (i >= j):
    return True
  return s[i] == s[j] and helper(s, i+1, j-1)

【讨论】:

    【解决方案4】:

    如果提到的函数签名def is_palindrome(s)是你老师给的签名,那么没有问题,不需要传递任何额外的参数来实现目标。

    你的老师(或者给你这个任务的老师太棒了)只是想检查一下你是如何只用 1 个参数来处理这个问题的。

    概念很简单,只需在第二次递归调用中更改参数(to list with 3 values)的类型即可。

    def is_palindrome(s):
        if type(s) is str:
            l = len(s) 
    
            if l == 0 or l == 1:
                return True
            else:
                return is_palindrome([s, 0, -1])
        else:
            string, start, end = s # s is list here
    
            if string[start] != string[end]:
                return False
            else:
                if(start + 1 >= end - 1):
                    return True
    
                return is_palindrome([s, start + 1, end - 1])
    
    def main():
        string1 = "abcba"
        string2 = "abcde"
        string3 = "AxxA"
    
        print(is_palindrome(string1)) # True
        print(is_palindrome(string2)) # False
        print(is_palindrome(string3)) # True
    
    main();
    

    以下不是您正在寻找的内容,但可能是您将来会寻找的内容。

    >>> def is_palindrome(s):
    ...     if s == "".join(reversed(s)):
    ...         return True
    ...     else:
    ...         return False
    ...
    >>> is_palindrome("ABA")
    True
    >>>
    >>> is_palindrome("ABC")
    False
    >>>
    >>> is_palindrome("XXZZXX")
    True
    >>>
    >>> is_palindrome("@#7")
    False
    >>>
    >>> is_palindrome("1@#@1")
    True
    >>>
    

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-05
      • 2010-12-16
      • 2018-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多