我为project Euler question #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中的类似代码在最顶部给出了最大的数字。我缺少Python for
循环吗?
答案 0 :(得分:1)
仔细研究产生该产品的价值会回答您的问题。第一个数字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--)
。
答案 1 :(得分:0)
这方面的技巧是循环从内循环迭代到外循环。首先,对于外部循环迭代内部值为999,然后为外部循环迭代内部循环以获得值998。
由此产生的产品不按降序排序(例如995 * 583&lt; 993 * 913,但由于x(产品的第一个元素)较高(外环),因此第一个产品计算得更早。)
答案 2 :(得分:0)
虽然已有更好的答案,但只发布输出的生成方式。 我刚修改了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
答案 3 :(得分:0)
这是您的代码版本,可以根据您的需要打印从最高到最低的值。
它更加优化,因为它避免了冗余乘法,并滤除了无论如何都会发生的重复。 (例如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()