为了更方便看到结果,这里采取小数据来算,不对的求大佬指正
一,最简单输出素数的算法
循环遍历数组,从2——二次方根x判断能否被整除
#include<iostream>
#include<cmath>
using namespace std;
int N = 20, cnt = 0;
inline bool is_prime(int x) {//判断素数
if (x == 2) return 1;
for (int i = 2; i <= sqrt(x); i++) {//用循环判断能否整除
if (x % i == 0) return 0;
}
return 1;
}
int main() {
for (int i = 2; i <= N; i++) {
if (is_prime(i)) cout << i << " ";
}
return 0;
}
缺点,耗时特别大,下面我们对它改进一下
二,朴素筛法
#include<iostream>
#include<cmath>
using namespace std;
int N = 20, cnt = 0;
bool arr[1000];//0为素数,1为合数(要被晒除去)
inline bool is_prime(int x) {//判断素数
if (x == 2) return 1;
for (int i = 2; i <= sqrt(x); i++) {//用循环判断能否整除
if (x % i == 0) return 0;
}
return 1;
}
int main() {
for (int i = 2; i <= N; i++) {
if (is_prime(i)) {
for (int j = 2 * i; j <= N; j+=i)
arr[j] = 1;
}
}
for (int i = 2; i <= N; i++) {
if (!arr[i]) cout << i << " ";
}
return 0;
}
即是建立一个数组,把质数的倍数记录下来,最后把质数输出
就像这个,把2下标为0记录下来,二的倍数删去,然后是下一个质数3,然后是5以此类推荐,通常这种算法耗时也大
三,欧式筛法
#include<iostream>
#include<cmath>
using namespace std;
int N = 2;
bool arr[1000];//0为素数,1为合数(要被晒除去)
int main() {
for (int i = 2; i <= N/i; i++) {
if (!arr[i]) {
for (int j = i * i; j <= N; j+=i)
arr[j] = 1;
}
for(int i=2;i<=N;i++)
cout<<i<<" ";
return 0;
}
应为它arr数组中存的数,更新前全是0,更新后,质数还是为零,下一个为零的数,它一定是不能整数前面数的质数,只需要直接判断就可以了
特点:耗时比较少
缺点:一个数可能被多次筛去
三,欧拉筛法
#include<iostream>
#include<cmath>
using namespace std;
int N = 20, cnt = 0;
bool arr[1000];//0为素数,1为合数(要被筛去)
int brr[1000];//存放质数
int main() {
for (int i = 2; i <= N; i++) {
if (!arr[i]) { brr[++cnt] = i; cout << brr[cnt] << " "; }
for (int j = 1; brr[j] * i<=N; j++) {//限制条件防溢出
arr[brr[j] * i] =1;//让可以倍数为1
if (i % brr[j]==0) break;//如果这个数可以被前面的整除
}
}
return 0;
}
解析在代码里面,建议自己画图
优点,耗时少,和埃氏筛法差不多
求个赞和收藏,谢谢