簡體   English   中英

最大質因數 - C++

[英]Largest Prime Factor- C++

我試圖找到數字 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");
}
num = 600851475143;

Integer 溢出發生在這里。 num的大小不足以包含您提供的值。

使用uint64_t

#include <cstdint>  //must include this!

uint64_t num = 600851475143;

閱讀: cstdint

代碼存在不少大問題,所以我想展示一個更好的完整解決方案。 主要問題是它沒有輸入驗證。 好的代碼必須在它不拒絕的所有輸入上都是正確的。 所以我現在已經包括正確閱讀和驗證輸入。 這樣,您就會自動發現問題。

所有主要類型都需要有專有名稱。 所以我介紹了typedef uint_type,編譯器也會在編譯時發現。 如果輸入 60085147514 是否有效(盡管現在在運行時也被拒絕),如果編譯器發出警告; 那么你需要使用更大的整數類型。 但是 unsigned long 在所有常見的 64 位平台上就足夠了(但不是在常見的 32 位平台上),如果您需要更大的 integer 類型。 那么現在只需要改變一個地方。

您的算法效率極低,所需要的只是將數字除以找到的所有因素(盡可能長)。 並且保證您只會遇到素數-因此無需檢查。 而且只需要考慮輸入平方根的因素。 這一切都需要一些邏輯來思考——看代碼。

那么你的代碼就違反了局部性原則:在需要它們的地方聲明你的變量,而不是在其他地方。 您還包括了非 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";
}

您可以將num變量聲明為long long int

long long int num;

這將避免代碼中發生的所有類型的溢出!

並提供更正。 根據您的編譯器,您可以嘗試 unsigned long 並查看是否可以保留您的答案。 嘗試寫入 cout 並查看變量是否保持您期望的值。

另一方面,如果您試圖找到最大的因素,從可能的最高因素開始倒數不是更有效嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM