欧拉计划挑战3:找到大数的最大素因数

Project Euler challenge 3: Finding the largest prime factor of a large number

本文关键字:计划 挑战      更新时间:2023-10-16

>找不到投影器的600851475143质因数。我的代码成功地计算了测试数 13195 的最大素因数和我扔给它的每一个测试数,但不知何故,它随着大素数而降级。你知道为什么吗?

#include <iostream>     
#include <queue>  
using namespace std;
int split(int split);
int largestprimefactor(priority_queue<int> myints);
int main()
{
int response = 2;
do{
    priority_queue<int> myints;
    int number;
    cout << "Please enter a number: ";
    cin >> number;
    myints.push(number);
    int lcf = largestprimefactor(myints);
    cout << endl << "Largest prime factor is: " << lcf;
    cout << endl << "Again?(1 for yes 2 for no): ";
    cin >> response;
}while(response == 1);
}
uint64_t split(uint64_t split)
{
if(split%2 != 0)
{
    if((split/2))%2 == 0)
        for(uint64_t i = (split/2)-1; i>1; i=i-2)
            if(split%i == 0)
                return i;
    else
        for(uint64_t i = (split/2); i>1; i=i-2)
            if(split%i == 0)
                return i;
    return 1;
}
else
    return 2;
}
int largestprimefactor(priority_queue<int> myints)
{
// largestfactor holds the next number to be tested for primeness in the queue
do{
    int largestfactor = myints.top();
    myints.pop();
    //splat will hold the first factor split finds of the top item in the queue
    int splat = split(largestfactor);
    //if it holds a 1 then that means that there are no factors
    if(splat != 1 && largestfactor)
    {
        myints.push(splat);
        myints.push(largestfactor / splat);
    }
    else
        return largestfactor;   
}while(myints.top() > 1);
}

您是否考虑过600851475143太大而无法存储在 32 位 int 中?

查看编译器为 64 位整数类型提供的内容。

我可能无法帮助您优化代码(我不确定您在split中做了什么),但这里有一个想法。

根据算术的基本定理,每个数字都有一个唯一的因式分解为素数的乘积。这意味着我们可以取一个数字并连续除以其质因数,直到达到 1。最后一个质数是答案。

现在,您只需要检查高达 sqrt(N) 的质因数。请注意,这并不意味着最大的素因数小于 sqrt(N),但如果有一个素因数大于 sqrt(N),则只有一个这样的素因数

这导致了以下 O(sqrt(N)) 算法:

long long largest_factor(long long number) {
    long long result = 0;
    for (long long i = 2; i * i <= number; ++i) {
        if (number % i == 0) {
            result = i;
            while (number % i == 0)
                number /= i;
        }
    }
    if (number != 1)
        return number;
    return result;
}

在600851475143上运行它给了我正确的答案。

600851475143 >> 32给出129,600851475143 >> 64给出3.10^-8。此数字太大,无法表示为 int,但您可以使用长度为 64 位的数字或设计用于表示较大整数的类来表示它。