实现思路
- 定义一个数组arr,包含从2到n的全部整数
- 将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}
优化
- 获取质因数的合数时,只需要乘以比质因数大的整数,避免重复(例如2×3和3×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]<<' ';
}
}
}