如何使用递归来使用Python查找回文?

时间:2011-03-31 05:41:56

标签: python recursion palindrome

我刚刚开始探索编程的奇迹。我正在尝试编写一个代码来识别数字回文。只是看数字而不是文本。我正试图在这里学习使用递归。但我只是没有到达任何地方,我无法弄清楚它有什么问题。

我的想法是检查第一个字符串与最后一个,然后删除这两个匹配,并重复。最终没有任何东西(暗示它是回文)或者会有一对不相符(暗示相反)。

我知道有更好的代码可以找到回文,但我只是想尝试一下递归。

那有什么不对?

def f(n):
    global li   
    li=list(str(n))
    if (len(li)==(1 or 0)):
        return True
    elif li[len(li)-1]==li[0]:
        del li[0]
        del li[len(li)-1]
        if len(li)==0:
            return True
        if len(li)>0:
            global x
            x=''.join(li)
            str(x)
            f(x)
    else:
      return False

提前致谢!

7 个答案:

答案 0 :(得分:5)

一些评论

  • 为什么xli全局?在递归中,所有变量都应该是本地的。
  • 为什么要在strlist之间来回转换?您可以下标both of them
  • 您需要返回递归调用的结果:return f(x)

尝试这些建议,看看它是如何运作的。

答案 1 :(得分:3)

在深入研究之前,if (len(li)==(1 or 0)):没有做到你期望它做的事情。 (1 or 0)将始终评估为1

你可能想要:

if len(li) in (1, 0):

答案 2 :(得分:3)

您的解决方案存在一些问题。让我逐行分析。

  1. 如果您不打算在函数范围之外更改变量,则不需要global语句。因此,我从您的代码中删除了两行global

  2. li=list(str(n)):将字符串转换为列表是不必要的,因为Python中的字符串具有与不可变列表类似的接口。所以一个简单的li = str(n)就足够了。

  3. if (len(li)==(1 or 0))::虽然它看起来不错,但实际上将值与其他一些值进行比较的方法并不正确。 or运算符从其左或右操作数返回第一个“true”值,因此在这种情况下它始终返回1。相反,您可以使用in运算符,该运算符检查左操作数是否是右操作数的元素。如果我们将右操作数设为元组(1, 0),那么一切都会很好。此外,if语句周围不需要括号。你应该写:if len(li) in (1, 0):

  4. elif li[len(li)-1]==li[0]:很好,但我们可以在Python中写得更短,因为它支持否定列表索引:elif li[-1] == li[0]:

  5. 因为第2点我们不使用列表(可变序列),所以我们不能对它们del li[0]。无论如何,删除列表的第一个元素在Python中是非常低效的(必须复制整个列表)。出于同样的原因,我们不能del li[len(li)-1]。相反,我们可以使用“拼接”运算符从字符串中提取子字符串:li = li[1:-1]

  6. if len(li)==0:是不必要的。在Python中,如果由if测试,则空字符串和列表将解析为False。所以你可以写if not li:

  7. if len(li)>0::您不必再次检查li是否为空 - 您在第6点进行了检查。因此,简单的else:就足够了。或者甚至更好,完全删除此行并取消函数的其余部分,因为6.中if的正文包含return。因此,如果我们没有输入if,我们就会在else中,而不会写任何内容。

  8. x=''.join(li):我们不需要将字符串转换为字符串,因为在2中做出了决定。删除此行。

  9. str(x):此行在您的代码中没有做任何有用的事情,因为str()不会修改其参数,而是返回一个新值(所以{{1}会更有意义)。您也可以将其删除。

  10. x = str(x):这是在Python中调用递归函数的有效方法,但您必须对其值执行某些操作。也许回来吧?我们会将其更改为:f(x)(因为我们不再有return f(li)变量)。

  11. 我们最终得到以下代码:

    x

    这几乎是我们所需要的,但仍然可以做一点改进。如果您查看def f(n): li = str(n) if len(li) in (1, 0): return True elif li[-1] == li[0]: li = li[1:-1] if not li: return True return f(li) else: return False 行,您会发现它们不是必需的。如果我们删除它们,那么if not li: return True将使用空字符串作为参数调用,f将等于0并且无论如何都将返回len(li)。所以我们将继续删除这些内容:

    True

    就是这样!祝你成为一名成功的程序员好运!

答案 3 :(得分:1)

将整个节目分成一个列表,然后只是:

def fun(yourList):
    if yourList.pop(0) == yourList.pop(-1):
        if len(yourList) < 2:
            return True # We're a palindrome
        else:
            return fun(yourList)
    else:
        return False # We're not a palindrome

print "1234321"
print fun(list("1234321")) # True
print "6234321"
print fun(list("6234321")) # False

答案 4 :(得分:0)

很难从代码中分辨出你打算做什么,但我写了一个更简单(也是递归)的例子,可以让你更容易理解:

def is_palindrome(num):
    s = str(num)
    if s[0] != s[-1]:
       return False
    elif not s[1:-1]:
       return True
    else:
       return is_palindrome(int(s[1:-1]))

答案 5 :(得分:0)

def palindrome(n):
    return n == n[::-1]

答案 6 :(得分:0)

number = int(raw_input("Enter a number: "))

rev = 0
neg = number

original = number


if (number < 0):
    number = number * -1

else:

    number = number

while ( number > 0 ):

     k = number % 10

     number = number / 10

     rev = k + ( rev * 10 )

     if (number < 1):
         break

if ( neg < 0 ):
    rev =  ( rev * -1)

else:

    rev = (rev)

if ( rev == original):

    print "The number you entered is a palindrome number"

else:

    print "The number you entered is not a palindrome number"

这个代码甚至适用于我在编程时出现任何错误的负数 别介意。