项目欧拉挑战3:寻找大数量的最大素数因子

时间:2013-12-23 09:22:07

标签: c++ algorithm

无法找到projecteuler的主要因子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);
}

3 个答案:

答案 0 :(得分:2)

您是否认为600851475143太大而无法存储在32位int?

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

答案 1 :(得分:1)

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

通过fundamental theorem of arithmetic,每个数字都具有对素数乘积的唯一因子分解。这意味着我们可以取一个数字并连续除以其素数因子直到达到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上运行它给了我正确的答案。

答案 2 :(得分:0)

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