我有以下为 project Euler question #4 编写的代码:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
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 中的类似代码在最上面给出了最大的数字。是否缺少有关 Python for
循环的内容?
最佳答案
仔细研究产品的值(value)就可以回答您的问题。第一个数字 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("%d\n", 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--)
。
关于Python嵌套for循环输出不可预测?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48378468/