【问题标题】:Finding Palindromes from the product of two numbers with N digits从两个 N 位数字的乘积中找到回文数
【发布时间】: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;

}

【问题讨论】:

  • 是的,但我想知道我的代码具体出了什么问题。
  • 我认为这里的教训是不要盯着代码看。了解如何使用调试器,你会在几秒钟内找到问题。
  • @tedled:你已经得到答案了,看看魏子尧的答案。
  • 这是我的代码中的复制/粘贴错误。这是帖子中的错误。

标签: c++ string algorithm


【解决方案1】:
for(int i = 999; i <=100; i--)

这会运行吗(j 也一样)? :)

for(int i = 999; i >=100; i--)

【讨论】:

  • 我把它从 100 开始改成了 900,并没有在我的帖子中更改它。在我的代码中是正确的。
【解决方案2】:

最大的不同是if(thisProduct &gt; biggestProduct)这一行。如果产品小于当前最大的,则不必检查是否是回文。

【讨论】:

    【解决方案3】:

    好的,假设对 for 循环进行了更正,那么这两段代码有一个重要的区别。第二个更快的代码只尝试找到最大的回文,所以它避免了很多工作。您的代码尝试查找所有回文,这显然是一个更难的问题,并且需要更多时间。

    【讨论】:

      【解决方案4】:

      两者的区别在于,第一个测试每个i*j的回文,而另一个只测试i*j大于它已经发现的最大回文。

      j= ij&gt;=100 并在i*j&lt;= biggestProducti*i&lt;= biggestProduct 时提前退出可以稍微加快速度。

      【讨论】:

        【解决方案5】:

        我可以指出以下几个问题:

        • 这行代码:for(int j=999; j&gt;=100;j--)可以简化为for(int j=999; j&gt;=i-1;j--)。这是为了避免两次跑过数字。 例如:对于 i=999,您将通过 j 计数器,从 999 开始,然后是 998、997 等。如果您跳过低于或等于 998 的所有内容,因为 i=&lt;998j=999 会导致这些组合
        • 第二个提示在问题中:您正在寻找最大的,这意味着第一个回文是最大的。因此,您需要过滤除此之外的任何组合。您可以在第二个代码中添加 if(thisProduct &gt; biggestProduct)
        • 计数器的步骤也很重要。从this discussion 我发现将步长更改为 2 可能很有用。

        • 最后但同样重要的是字符串。我还了解到here 制作字符串的计算成本可能很高。使用std::string 编辑块可能是另一种选择。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多