从两个 N 位数字的乘积中找到回文数
Posted
技术标签:
【中文标题】从两个 N 位数字的乘积中找到回文数【英文标题】:Finding Palindromes from the product of two numbers with N digits 【发布时间】:2011-08-17 20:00:41 【问题描述】:我的代码可以编译,但似乎永远找不到答案。这很奇怪,因为我查看了几秒钟内完成的几乎相同的代码。
这是我的代码:
#include <iostream>
#include <sstream>
int main()
for(int i = 999; i >=100; i--)
for(int j=999; j>=100;j--)
int num = (i*j);
std::string number;
std::string temp;
std::string reversed;
std::stringstream out;
out << num;
number = out.str();
temp = number;
std::reverse(temp.begin(),temp.end());
if( temp == number)
std::cout << number << std::endl;
std::cin.get();
return 0;
现在这里是我知道可以运行并且运行速度非常快的代码。我看不出我们在做什么不同。
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
// Count down from largest to smallest, so first palindrome found is the largest
unsigned biggestProduct = 0;
for(unsigned n1=999; n1>=100; --n1)
for(unsigned n2=999; n2>=100; --n2)
unsigned thisProduct = n1 * n2;
if(thisProduct > biggestProduct)
stringstream strmProduct;
string strProductReverse;
strmProduct << n1 * n2;
strProductReverse = strmProduct.str();
reverse(strProductReverse.begin(), strProductReverse.end());
if(strmProduct.str() == strProductReverse)
biggestProduct = thisProduct;
cout << biggestProduct << endl;
cin.get();
return 0;
【问题讨论】:
相关:***.com/questions/7000168/project-euler-problem-4 是的,但我想知道我的代码具体出了什么问题。 我认为这里的教训是不要盯着代码看。了解如何使用调试器,你会在几秒钟内找到问题。 @tedled:你已经得到答案了,看看魏子尧的答案。 这是我的代码中的复制/粘贴错误。这是帖子中的错误。 【参考方案1】:for(int i = 999; i <=100; i--)
这会运行吗(j 也一样)? :)
for(int i = 999; i >=100; i--)
【讨论】:
我把它从 100 开始改成了 900,并没有在我的帖子中更改它。在我的代码中是正确的。【参考方案2】:最大的不同是if(thisProduct > biggestProduct)
这一行。如果产品小于当前最大的,则不必检查是否是回文。
【讨论】:
【参考方案3】:好的,假设对 for 循环进行了更正,那么这两段代码有一个重要的区别。第二个更快的代码只尝试找到最大的回文,所以它避免了很多工作。您的代码尝试查找所有回文,这显然是一个更难的问题,并且需要更多时间。
【讨论】:
【参考方案4】:两者的区别在于,第一个测试每个i*j
的回文,而另一个只测试i*j
大于它已经发现的最大回文。
从j= i
到j>=100
并在i*j<= biggestProduct
或i*i<= biggestProduct
时提前退出可以稍微加快速度。
【讨论】:
【参考方案5】:我可以指出以下几个问题:
这行代码:for(int j=999; j>=100;j--)
可以简化为for(int j=999; j>=i-1;j--)
。这是为了避免两次跑过数字。
例如:对于 i=999
,您将通过 j
计数器,从 999 开始,然后是 998、997 等。如果您跳过低于或等于 998 的所有内容,因为 i=<998
和 j=999
会导致这些组合
第二个提示在问题中:您正在寻找最大的,这意味着第一个回文是最大的。因此,您需要过滤除此之外的任何组合。您可以在第二个代码中添加 if(thisProduct > biggestProduct)
。
计数器的步骤也很重要。从this discussion 我发现将步长更改为 2 可能很有用。
最后但同样重要的是字符串。我还了解到here 制作字符串的计算成本可能很高。使用std::string
编辑块可能是另一种选择。
【讨论】:
以上是关于从两个 N 位数字的乘积中找到回文数的主要内容,如果未能解决你的问题,请参考以下文章