项目Euler#4与python。我的代码出了什么问题?

时间:2015-07-30 13:07:46

标签: python python-2.7

我正在尝试使用python做项目euler问题4。问题陈述是这样的:

  

回文数字两种方式相同。由两个2位数字的乘积制成的最大回文是9009 = 91×99。

     

找出由两个3位数字的乘积制成的最大回文。

我写下了一个解决方案:

s=0
x=100
y=100
list=[]
z=x*y
def palindrome():
    while z>=1:
        s=s*10+z%10
        z=z/10
        if z==s:
            list.append(z)
while x<=999:
    while y<=999:
        palindrome()
        y=y+1
    x=x+1
    y=100
print list

它最终给出了一个错误,就是'z引用超出赋值'。

在最终决定使用语法'global'绕过此错误之前,我搜索了此错误的解决方案。

s=0
x=100
y=100
list=[]
z=x*y
def palindrome():
    global z
    global s
    global x
    global y
    global list
    while z>=1:
        s=s*10+z%10
        z=z/10
        if z==s:
            list.append(z)
while x<=999:
    while y<=999:
        palindrome()
        y=y+1
    x=x+1
    y=100
print list

现在它没有给出错误,但是它给出了一个空列表作为输出。我尝试通过在两者之间插入print语句来调试代码。循环似乎工作正常,因为'x'和'y'打印它们应该的所有值。但是,我得到一个空列表作为print list命令的输出,'z'显然没有改变值,并且尽管我使用while循环来改变x和y的值,但它仍然停留在100000。

我对如何从这里开始感到茫然。

2 个答案:

答案 0 :(得分:2)

你得到的错误可能是:

UnboundLocalError: local variable 'z' referenced before assignment

这意味着z未定义,至少不在palindrome()函数内。您添加global关键字的解决方案在技术上是正确的。但是,正如其他人已经指出的那样,使用全局变量会使代码难以理解。

我不清楚palindrome()应该做什么。它应该检查一个数字是否是回文?产生回文数?要解决此问题,您应该考虑构建代码。当然,有很多方法可以做到这一点,随着时间的推移,你会找到自己的风格。

那么,我的建议是考虑如何解决这个问题。如果您不了解解决方案,编码不会对您有所帮助。有时,在解决像这样的问题时,我会在不声明自己身体的情况下编写函数。您可以自上而下或自下而上执行此操作。例如:

def is_palindrome(n):
    """ Check if n is a palindrome number. """
    pass

def multiples_of_3_digits():
    """ Return all numbers that are the product of two 3-digit numbers ."""
    pass

def main():
    print max(n for n in multiples_of_3_digits() if is_palindrome(n))

通过这种方式,您可以专注于解决问题,然后再进行实际编码。也许您会添加帮助函数或意识到您可以以更有效的方式解决问题,但这只是一个开始。祝你好运!

答案 1 :(得分:0)

min=100
max=999
max_palindrome = 0
for a in range(min,max + 1):
    for b in range(a + 1, max + 1):
        prod = a*b
        if prod > max_palindrome and str(prod)==(str(prod)[::-1]):
            max_palindrome = prod
print max_palindrome

这里我们只关注最大回文,所以一旦知道非最大值,我们就不会花费任何时间存储其他回文。此外,在使用字符串强制转换和列表切片检查该数字是否为回文之前,if语句首先检查给定产品是否大于最大已知回文数。这应该会加速我们的代码,因为无论相关产品是否是回文,大于比较通常都会失败。当我们运行时,我们得到以下结果。

906609

替代方式:

由于其他人指出的原因,我不鼓励你使用全局变量。我也希望你参考安德烈的方法,因为它会教你自己组织。在这种方法中我也将使用2个函数is_palindrome(num)[检查数字是否为回文]和find_max_palindrome [找到最大的回文]

def is_palindrome(num):
    reversed = 0
    original = num

    if num < 10:
        return True
    if num % 10 == 0:
        return False

    while num >= 1:
        reversed = (reversed * 10) + (num % 10)
        num = num/10

    if original == reversed:
        return True
    else:
        return False

def find_max_palindrome():
    max_palindrome = 0
    a = 999
    b = 999
    prod = 0

    while a > 99:
        b = 999
        while b >= a:
            prod = a*b
            if prod > max_palindrome and is_palindrome(prod):
                max_palindrome = prod
            b = b -1
        a = a - 1

    return max_palindrome

print find_max_palindrome()