我有以下代码,这是我为项目欧拉问题#4编写的:
回文数的两种读法相同。由两个 2 位数字的乘积构成的最大回文是 9009 = 91 × 99。
找到由两个 3 位数字的乘积制成的最大回文。
def foo():
for x in xrange (999,100,-1):
for y in xrange (999,100,-1):
product= (x*y)
if str(product)== str(product)[::-1]:
print product
foo()
这段代码生成所有回文的连续输出,因为我省略了一个中断。但是,输出如下所示:
580085
514415
906609
119911
282282
141141
853358
650056
601106
..
..
我不知道为什么最大的数字不先打印出来。C 中的类似代码在最顶部给出最大的数字。我缺少关于 Pythonfor
循环的东西吗?
仔细研究生产产品的价值会回答您的问题。第一个数字,580085
由x = 995
和y = 583
产生。同样,第三种产品906609
由x = 993
和y = 913
生产。循环按预期反向迭代。
碰巧的是,最大的回文不一定需要由最大的乘法生成。
如果要查找最大的回文,请将此函数转换为生成器,并对其调用max
。此外,正如评论中指出的那样,您将迭代每对数字两次,一次作为 x-y 对,另一次作为 y-x 对。稍微修改第二个循环,这样就不必执行这些冗余计算。y
应该下降到x
,而不是100
。
def foo(l, u):
for x in xrange(u, l, -1):
for y in xrange(u, x - 1, -1):
v = x * y
if str(v) == str(v)[::-1]:
yield v
这样称呼它:
>>> max(foo(100, 999))
906609
对于 python-3.x,请将xrange
更改为range
。
我也很好奇,当你谈论C代码给你预期的输出时,你的意思是什么。所以我写了一点代码来测试:
#include <stdio.h>
#include <string.h>
char buf[42];
# https://stackoverflow.com/a/31397607/4909087
int is_palindrome(char const* s)
{
int len = strlen(s);
if ( len == 0 ) // An empty string a palindrome
{
return 1;
}
int i = 0;
int j = len-1;
for ( ; i < j; ++i, --j )
{
if ( s[i] != s[j] )
{
// the string is not a palindrome.
return 0;
}
}
// If we don't return from inside the for loop,
// the string is a palindrome.
return 1;
}
int main(){
int x, y;
for (x = 999; x >= 100; x--)
for (y = 999; y >= 100; y--)
{
sprintf(buf, "%d", x * y);
if(is_palindrome(buf)){
printf("%dn", x * y);
}
}
return 0;
}
编译并运行此结果:
$ gcc test.c
$ ./a.out
580085
514415
906609
119911
282282
141141
853358
650056
601106
592295
543345
485584
...
这与你通过python程序得到的数字完全相同。请注意,这仍然效率低下,正确的方法是将内部循环的定义更改为for (y = 999; y >= x; y--)
。
这样做的诀窍是循环从内部循环迭代到外部循环。首先,对于外部循环,使用值 999 迭代内部循环,然后迭代内部循环,对于外部循环的值为 998。
生成的乘积不是按递减顺序排序的(例如 995 * 583 <993 * 913,但第一个乘积计算得更早,因为 x(乘积的第一个元素)更高(外循环))。
虽然已经有更好的答案,但只需发布输出是如何生成的。 我刚刚修改了 Py3 的代码。正如其他人所解释的那样,这种行为是正常的。由于外循环的 x 值将减少 1,因此只有当内循环的 y 达到 100 时,您看到的输出不是降序的。
for x in range(999,100,-1):
for y in range(999,100,-1):
product= (x*y)
if str(product)== str(product)[::-1]:
print('x is ' + str(x) + '; y is ' + str(y))
print(product)
输出:
x is 995; y is 583
580085
x is 995; y is 517
514415
x is 993; y is 913
906609
x is 991; y is 121
119911
x is 987; y is 286
282282
x is 987; y is 143
141141
x is 982; y is 869
853358
x is 979; y is 664
650056
x is 979; y is 614
601106
x is 979; y is 605
592295
x is 979; y is 555
543345
x is 979; y is 496
485584
x is 979; y is 446
436634
x is 979; y is 387
378873
x is 979; y is 337
329923
x is 978; y is 418
408804
下面是一个代码版本,它将在你查找时从高到低打印值。
它更优化一些,因为它避免了多余的乘法,并过滤掉了无论如何都可能发生的重复项。 (例如 111*9 == 333*3 == 999)。
我在Python 3中做到了这一点。 您可能需要手动导入 Python 2 的 Set 模块。
def foo():
result = set()
for x in range (999,1,-1):
for y in range (999,x,-1):
product= (x*y)
if str(product)== str(product)[::-1]:
result.add(x*y)
result = list(result)
result = sorted(result,reverse=True)
for i in result:
print(i)
foo()