Python中的回文数

2 投票
6 回答
7949 浏览
提问于 2025-04-17 20:43

我正在尝试找出两个三位数相乘得到的最大回文数。在我去查找更高效的、而且更重要的是有效的解决方案之前,你能告诉我我的代码哪里出问题了吗?我总是得到一个空的结果。

def palindrome():
    n = 100
    m = 100
    palind = []
    while n<=999:
        while m<=999:
            prod = n * m
            if str(prod) == str(prod)[::-1] and prod > palind[0]:
                palind.pop(0)
                palind.append(prod)
            return palind
            m = m + 1
        n = n + 1
        return palind

print palindrome()

6 个回答

0

这可能不是直接回答问题,但如果你想在某个范围内找回文数字,可以这样做:

def getPalindrome(lower, upper):
  listPalind = []
  for n in range(lower, upper):
    if str(n) == str(n)[::-1]:
      listPalind.append(n)
  return listPalind

# Usage
print(getPalindrome(100, 300))

# Results
[101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292]
0

这段代码是用来处理一些数据的。它的主要作用是从一个地方获取信息,然后对这些信息进行一些操作,最后把结果输出。具体来说,它可能会涉及到循环、条件判断等基本的编程概念。

在编程中,我们经常需要从一个数据源(比如数据库或文件)读取数据,然后对这些数据进行分析或修改。这个过程通常包括以下几个步骤:

1. **获取数据**:首先,我们需要从某个地方拿到数据。这可能是通过读取文件、查询数据库等方式。

2. **处理数据**:拿到数据后,我们会对这些数据进行一些操作,比如筛选出我们需要的信息,或者对数据进行计算。

3. **输出结果**:最后,我们会把处理后的结果展示出来,可能是打印到屏幕上,或者保存到文件中。

这段代码的具体实现可能会用到一些编程语言的基本语法,比如变量、函数、循环等。理解这些基本概念后,你就能更好地理解这段代码在做什么了。

def isPalindrome(self, x: int):
    temp = 0
    x1 = x
    while x > 0:
        y = x % 10
        temp = temp * 10 + y
        x = x//10

    if(temp == x1):
        return True
    else:
        return False
1
  1. 你没有在每次外层循环的迭代后重新设置 m = 100

  2. 你提前返回了结果。把内层循环中的 return 语句去掉。

  3. 最后的 return 语句不应该放在外层循环里面。

  4. 你从来没有初始化过 palind 列表(感谢 @user2357112)。

建议:

  1. 不要用列表来保存最大的数字,简单的变量就够了。

  2. 在同一个表达式中,不需要把数字转换成字符串两次。可以把转换后的字符串存到一个变量里。

  3. 使用 range 函数来循环遍历数字。

如果我来写这个程序,我会这样做:

from itertools import product
def palindrome():
    numbers, result = range(1000, 100, -1), -1
    for num1, num2 in product(numbers, repeat = 2):
        prod  = num1 * num2
        sprod = str(prod)
        if sprod == sprod[::-1] and prod > result:
            result = prod
    return result

print palindrome()   # 906609
3

这个快捷方式的作用是,当无法找到一个 i*j 大于已记录的最大值时,它能正确返回 906609(注意,如果你使用的是 Python 2,下面的代码对你有效,但你最好用 xrange 代替 range,这样可以避免在内存中创建不必要的列表):

def palindrome(floor=0, upto=999):
    '''
    return the largest palindrome product for all number from (but not including)
    floor to (and including) upto 
    '''
    start = upto
    largest = None
    for i in range(start, floor, -1): # decreasing from upto
        if i * upto < largest: # if True, impossible for higher product from combo
            break 
        for j in range(start, i-1, -1): # decrease from upto to not including i-1
            product = i*j
            if str(product) == str(product)[::-1]:
                if product > largest:
                    largest = product
    return largest

用法:

>>> palindrome(99,999)
906609
>>> palindrome(10,13)
121
>>> palindrome(0,10)
9

这个快捷方式很重要,因为如果给一个非常大的数字,返回结果可能会花费很长时间:

>>> palindrome(upto=100000000)
9999000000009999L

我还创建了一个生成器,它会遍历从 0 到 999 的每一种组合,并且返回 906609。

def palindrome(upto=1000):
    return max(i*j for i in range(upto) for j in range(upto) 
                if str(i*j) == str(i*j)[::-1])

但是当运行这个回文数时,如下所示:

>>> palindrome(upto=100000000)

完整的搜索会检查所有 100000000^2 的组合,耗时会非常长。

我最开始是这样写的,想着可以通过快捷方式避免遍历每一种可能的组合,但这样是错误的,它返回的是 888888:

def palindrome():
    start = 999
    largest = 0
    for i in range(start, 0, -1): # decreasing from 999
        if i * 999 < largest:
            return largest
        for j in range(start, i, -1): # decreasing from 999 to i
            if str(i*j) == str(i*j)[::-1]:
                largest = i*j

它首先计算 999 乘以 999,然后是 998 乘以 999,然后

998*998
997*999
997*998
997*997
...

但结果并不是单调递减的(也就是说,每个结果并不一定小于前一个结果)。

3

你有三个问题。

问题1:提前返回。

while n<=999:
    while m<=999:
        prod = n * m
        if str(prod) == str(prod)[::-1] and prod > palind[0]:
            palind.pop(0)
            palind.append(prod)
        # Here
        return palind
        m = m + 1
    n = n + 1
    # And here
    return palind

一个 return 语句意味着这个函数现在就结束了。它会在当前位置停止,调用这个函数的地方会得到返回值,然后继续执行后面的代码。你不想在函数还没完成所有工作之前就这样结束。我们应该把 return 移到循环之后,也就是函数完成计算之后再返回。

问题2:palind[0] 没有初始化。

while n<=999:
    while m<=999:
        prod = n * m
        #                                           Here  v
        if str(prod) == str(prod)[::-1] and prod > palind[0]:
            palind.pop(0)
            palind.append(prod)
        m = m + 1
    n = n + 1
return palind

假设你的程序在运行时找到了第一个回文字符串。它试图把这个回文字符串和 palind[0] 进行比较,但 palind[0] 根本不存在!你需要先获取第一个回文字符串,而不是试图去比较一个不存在的值。我们来解决这个问题。

问题3:没有重置 m

palind = None
while n<=999:
    while m<=999:
        prod = n * m
        if str(prod) == str(prod)[::-1]:
            if palind is None or prod > palind:
                palind = prod
        m = m + 1
    n = n + 1
return palind

n 循环的第一次迭代之后,你需要用 n=101 的值重新遍历所有可能的 m 值。但你没有这样做;你的代码把 m 保持在 1000,所以它不会再进入内层循环。你可以手动重置 m,但使用 for 循环会比 while 循环简单得多。解决了这三个问题后,你的代码看起来像这样:

palind = None
for n in xrange(100, 1000):
    for m in xrange(100, 1000):
        prod = n * m
        if str(prod) == str(prod)[::-1]:
            if palind is None or prod > palind:
                palind = prod
return palind

撰写回答