埃拉托色尼筛 - 主要因素

Posted

技术标签:

【中文标题】埃拉托色尼筛 - 主要因素【英文标题】:Sieve of Eratosthenes - prime factor 【发布时间】:2016-09-05 22:17:39 【问题描述】:

我刚刚写了以下内容,以利用筛子找到大于 2 的某个自然数的最大素数。

该程序针对较小的测试值构建、运行和工作,但对于大于 1000000 的值只会崩溃。

我自己写了这个——并且相信它可能会非常低效——在找出筛子的用途之后。

您能否提出改进建议?

谢谢。

//LARGEST PRIME FACTOR w/SIEVE OF ERATHOSTHENES
#include <iostream>
#include <math.h>

using namespace std;

unsigned long long int numberToCheck=0;

void sieve(unsigned long long int checkNumber)

    checkNumber=numberToCheck;
    unsigned long long int root=(int)(sqrt(checkNumber));
    unsigned long long int primeFlagger[checkNumber+1];

    for(unsigned long long int i=0;i<=checkNumber;i++)
    
        primeFlagger[i]=1;
    

    primeFlagger[0]=0;
    primeFlagger[1]=0;

    for(unsigned long long int j=2;j<=checkNumber;j++)
    
        if(primeFlagger[j]==1)
        
            for(unsigned long long int k=2;(k*j)<=checkNumber;k++)
            
                primeFlagger[j*k]=0;
            
        
    

    for(unsigned long long int l=checkNumber;l>=0;l--)
    
        if(primeFlagger[l]==1)
        
            if(checkNumber%l==0)
            
                cout<<l<<" is the largest prime factor"<<endl;
                break;
            
        
    


int main()

    cout<<"Largest prime factor less then or equal to? "<<endl;
    cin>>numberToCheck;
    cout<<endl;
    cout<<"Retrieving largest prime factor..."<<endl;

    sieve(numberToCheck);



    return 0;

【问题讨论】:

埃拉托色尼筛法非常适合在某个连续范围内生成中等大小的素数表。虽然它可以用于试除法(找到给定输入的最小素因数),但它有点不必要的矫枉过正。您能否更深入地解释一下您的计划目标? 应该生成大于2的某个自然数的最大素因数。 【参考方案1】:

sieve 函数内的数组 unsigned long long int primeFlagger[checkNumber+1]; 太长。在全局范围内使用数组,在任何函数或动态内存分配之外。

另外,你不需要unsigned long long。它是最大的整数数据类型,您只使用其中的一位。将类型更改为 bool 也会对您有所帮助。

还有其他问题:

unsigned long long int root=(int)(sqrt(checkNumber)); - 如果数字真的很大,sqrt(checkNumber) 会溢出 int; unsigned long long int primeFlagger[checkNumber+1]; - checkNumber 的类型可能大于 std::size_t - 数组索引的类型并且大于可以分配的最大内存区域。您不能将数组大小设为 unsigned long long。 checkNumber=numberToCheck; - 你不需要这个。 numberToCheck 已经作为参数 checkNumber 传递给函数。 sieve 内部的 checkNumber 将等于 numberToCheck; for(unsigned long long int j=2;j&lt;=checkNumber;j++) - 这个循环应该在 j&lt;=root 之后结束。这足以标记所有非原始数字。

如果您确实需要处理如此大的数字,请使用segmented sieve。

【讨论】:

以上是关于埃拉托色尼筛 - 主要因素的主要内容,如果未能解决你的问题,请参考以下文章

埃拉托色尼筛算法

埃拉托色尼筛的问题

埃拉托色尼筛法及线性筛法

埃拉托色尼筛 - 寻找素数 Python

通过埃拉托色尼筛算法(C++)查找素数

使用埃拉托色尼筛法找到第 n 个素数