【问题标题】:Largest Prime Factor- C++最大质因数 - C++
【发布时间】:2011-08-15 07:07:41
【问题描述】:

我正在尝试找到数字 600851475143 的最大素因子。我的代码适用于我测试的较小数字(低于 100)。然而,当遇到 600851475143 时,它返回 4370432,绝对不是素数。任何想法我的代码可能有什么问题?

#include <iostream>
#include <time.h>
#include <math.h>

using namespace std;

int main()
{

int num;
int largest;
int count;

cout<<"Please enter a number to have its Largest Prime Factor found"<<endl;
cin>>num;
num = 600851475143;

for (int factor = 1; factor <= num; factor++)
{
    if (num % factor == 0)
    {
        count = 0;
        for (int primetest=2; count == 0 && factor > primetest ; primetest++) 
        {
            if (factor % primetest == 0)
            count ++;    
            //endif
        }
        if (count == 0)
        largest = factor;
        //endif
    }       

}//endif
cout<<largest<<endl;
system("PAUSE");
}

【问题讨论】:

标签: c++ prime-factoring


【解决方案1】:
num = 600851475143;

此处发生整数溢出。 num 的大小不足以容纳您提供的值。

使用uint64_t

#include <cstdint>  //must include this!

uint64_t num = 600851475143;

阅读:cstdint

【讨论】:

  • 好的,这就解释了。如果您不介意,能否提供一个可以包含此类值的非浮点数据类型?
  • @user894575 :立即查看我的答案。
  • 整数字面量需要相应大:600851475143ull
  • @Gene:但是现在你假设存在一个 64 位的unsigned long long?有了这个假设,为什么还要麻烦cstdint 标头?
  • 总是将你的编译器设置为最高的健全警告级别,然后它会告诉你这样的溢出。 C99 和 C++11 具有可选的固定宽度整数类型,例如 uint64_t,这可能会有所帮助。使用 std::numeric_limits::digits10 确定类型是否足以满足您的需求。如果您需要更多位数,请使用 gmp 等任意精度库。
【解决方案2】:

代码有不少大问题,所以我想展示一个更好的完整 解决方案。主要问题是它没有输入验证!好的代码必须是正确的 在所有输入上它都不会拒绝。所以我现在已经包括正确阅读和验证 输入。这样一来,您就会自动发现问题。

所有主要类型都需要有专有名称!所以我介绍了typedef uint_type。 如果输入 60085147514 是 有效与否(尽管现在在运行时也被拒绝)。如果编译器发出警告, 那么你需要使用更大的整数类型;但是 unsigned long 在所有常见的情况下就足够了 64 位平台(但不在常见的 32 位平台上)。如果您需要更大的整数类型, 那么现在只需要改变一个地方。

您的算法效率极低!所需要的只是将数字除以 找到所有因素(尽可能长),并且保证您只遇到素数 数字——所以不需要检查。而且一个只需要考虑的因素高达 输入的平方根。这一切都需要一些逻辑来思考——见 代码。

那么你的代码就违反了局部性原则:声明你的变量在哪里 需要,而不是其他地方。您还包括了非 C++ 标头,此外还有 没有必要。 using-directives 的使用只是混淆了代码:你看不到了 组件来自哪里;并且不需要它们!我还介绍了一个 匿名命名空间,用于更突出的定义。

最后,我使用了更紧凑的编码风格(缩进 2 个空格,括号放在 同一行,尽可能避免使用括号。想一想:这样你可以看到很多 一目了然,同时经过一些培训也更容易阅读。

如图所示编译时,编译器会警告最大因子可能未定义。 事实并非如此,我在这里选择将该警告视为空的。

Program LargestPrimeFactor.cpp:
// Compile with
// g++ -O3 -Wall -std=c++98 -pedantic -o LargestPrimeFactor LargestPrimeFactor.cpp

#include <string>
#include <iostream>

namespace {
  const std::string program_name = "LargestPrimeFactor";
  const std::string error_output = "ERROR[" + program_name + "]: ";
  const std::string version_number = "0.1";

  enum ErrorCodes { reading_error = 1, range_error = 2 };
  typedef unsigned long uint_type;
  const uint_type example = 600851475143; // compile-time warnings will show
  // whether uint_type is sufficient
}

int main() {

  uint_type number;
  std::cout << "Please enter a number to have its largest prime factor found:"
   << std::endl;
  std::cin >> number;
  if (not std::cin) {
    std::cerr << error_output << "Number not of the required unsigned integer"
     " type.\n";
    return reading_error;
  }
  if (number <= 1) {
    std::cerr << error_output << "Number " << number << " has no largest prime"
     " factor.\n";
    return range_error;
  }
  const uint_type input = number;

  uint_type largest_factor;
  for (uint_type factor = 2; factor <= number/factor; ++factor)
    if (number % factor == 0) {
      largest_factor = factor;
      do number /= factor; while (number % factor == 0);
    }
  if (number != 1) largest_factor = number;

  std::cout << "The largest prime factor of " << input << " is " << largest_factor
   << ".\n";
}

【讨论】:

    【解决方案3】:

    并提供更正。根据您的编译器,您可以尝试 unsigned long 并查看是否可以保留您的答案。尝试写入 cout 并查看变量是否保持您期望的值。

    另一方面,如果您试图找到最大的因子,从可能的最高因子倒数会不会更有效率?

    【讨论】:

      【解决方案4】:

      您可以将您的 num 变量声明为 long long int

      long long int num;
      

      这将避免代码中发生的所有类型的溢出!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-26
        • 2023-03-17
        • 2023-01-13
        • 1970-01-01
        • 2011-08-17
        • 2020-09-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多