求小于等于n的质数

386 阅读2分钟

实现思路

  1. 定义一个数组arr,包含从2到n的全部整数
  2. 将arr中的合数去掉

详细解释

这个算法的关键在于,理解下面这条性质:
假如有两个相邻的质数a,b,且a<b,那么a和b之间的合数,至少有一个质因数小于等于a。
通过这个性质,我们从最小的质因数2开始,去掉arr中以2为质因数的合数,得到的下一个数就必定是质数,也就是第二小的质数,再去掉以它为质因数的合数,就可以得到第三小的质数,以此类推就可以得到小于等于n的全部质数。

举个简单的例子:n=10
那么arr={2,3,4,5,6,7,8,9,10};
其中以2为质因数的合数有:4,6,8,10,去掉这些合数后arr={3,5,7,9}
可以得到2的下一位质数是3,那么再去掉以3为质因数的合数:9,可以得到arr={3,5,7}
再依次执行5,7就可以得到最终答案是{3,5,7}

优化

  1. 获取质因数的合数时,只需要乘以比质因数大的整数,避免重复(例如2×3和3×2重复)。
  2. 在1的基础上,质因数只需要到根号n即可,如果质因数大于根号n,再乘以比自身大的数,得到的合数就大于n了,没有用。

完整代码

#include<iostream>
using namespace std;

int main(){

    int n;
    cin>>n;

    //把2到n全部质数添加进数组
    int arr[n-1];
    for(int i=0;i<n-1;i++){
        arr[i]=i+2;
    }

    //把合数全部置为-1
    for(int i=2;i*i<n-1;i++){ // i是质因数
        for(int j=i;i*j<=n;j++){ // i*j是积
            arr[i*j-2]=-1;
        }
    }

    //输出质数
    for(int i=0;i<n-1;i++){
        if(arr[i]!=-1){
            cout<<arr[i]<<' ';
        }
    }
}