1

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

我的想法是检查第一个字符串与最后一个字符串,然后如果它们匹配则删除这两个,然后重复。最终将一无所有(暗示它是回文),或者会有一对不匹配(暗示相反)。

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

那么有什么问题呢?

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

提前致谢!

4

7 回答 7

5

几点评论

  • 为什么是xli全局变量?在递归中,所有变量都应该是本地的。
  • str你为什么在and之间来回转换list?你可以给他们两个下标
  • 您需要返回递归调用的结果: return f(x)

试试这些建议,看看效果如何。

于 2011-03-31T05:48:42.407 回答
3

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

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

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

  3. if (len(li)==(1 or 0))::虽然看起来不错,但实际上将一个值与其他几个值进行比较是一种不正确的方法。or运算符从其左操作数或右操作数返回第一个“真”值,因此在这种情况下它总是返回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. 所以你可以写if not li:

  7. if len(li)>0:li:如果不是空的,您不必再次检查 - 您在第 6 点检查过它。所以一个简单的else:就足够了。或者更好的是,完全删除这一行并取消缩进函数的其余部分,因为if6. 中的主体包含一个return. 因此,如果我们没有进入if,我们根本就else没有写它。

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

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

  10. f(x): 这是在 Python 中调用递归函数的有效方法,但你必须对它的值做一些事情。或许退货?我们将其更改为:(return f(li)因为我们不再有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,您会发现它们不是必需的。如果我们删除它们, thenf将使用空字符串作为参数调用,len(li)将等于 0 并且True无论如何都会返回。所以我们将继续删除这些行:

def f(n):
    li = str(n)
    if len(li) in (1, 0):
        return True
    elif li[-1] == li[0]:
        li = li[1:-1]
        return f(li)
    else:
        return False

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

于 2011-03-31T11:00:48.183 回答
3

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

你可能想要:

if len(li) in (1, 0):
于 2011-03-31T05:43:56.120 回答
1
def palindrome(n):
    return n == n[::-1]
于 2013-09-24T11:14:15.100 回答
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
于 2011-03-31T05:47:31.223 回答
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"

这段代码甚至适用于负数,我是编程新手,万一出现任何错误,请不要介意。

于 2014-08-25T04:56:04.517 回答
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]))
于 2011-03-31T05:47:10.100 回答