埃拉托色尼筛选算法
用来产生一个不大于给定整数n的连续质数序列,
可应用于求质因数,其基本流程为:
- 初始化一个2~n的连续整数序列,作为候选质数;
- 消去2的倍数;
- 消去3的倍数;
- ... ...
- 注意判断循环条件(sqrt(n)向下取整),以及对已经消去数字的标记。
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
2 | 3 | √ | 5 | √ | 7 | √ | 9 | √ | 11 | √ | 13 | √ | 15 | √ | 17 | √ | 19 | √ | 21 | √ | 23 | √ | 25 |
2 | 3 | √ | 5 | √ | 7 | √ | √ | √ | 11 | √ | 13 | √ | √ | √ | 17 | √ | 19 | √ | √ | √ | 23 | √ | 25 |
2 | 3 | √ | 5 | √ | 7 | √ | √ | √ | 11 | √ | 13 | √ | √ | √ | 17 | √ | 19 | √ | √ | √ | 23 | √ | √ |
得到的质数序列为:{2,3,5,7,11,13,17,19,23}
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
// 埃拉托斯特尼筛法(筛选素数)
ll N = 1000 * 10000; // 数组过大会溢出
int *a = NULL;
a = (int*)malloc(sizeof(int)*N); // 动态申请内存可以防止数组过大的导致的内存溢出(开辟在堆区);直接int a[n]; 会开辟在栈区
for(int i=2; i<N; i++){
a[i] = i; // 初始化数组
}
for(int i=2; i<sqrt(N); i++){ // 只需要从2筛到N^(1/2)就行了
if(a[i] != 0){ // a[i]如果被筛掉了就设置为0
int j = i*i; // 从当前数的平方开始筛
while(j <= N){
a[j] = 0;
j = j + i; // 每次加上当前数,这样就相当于j = i*(i+1),都是i的倍数
}
}
}
int m = 0; // 记录共有多少个素数
cout << "素数序列:";
for(int i=2; i<N; i++){
if(a[i] != 0){
cout << a[i] << ' '; // 输出素数序列
m++;
}
}
cout << "\n\n素数个数为:" << m;
return 0;
}