筛:开一个数组 循环一遍判断是否为素数
暴力判别
int isprime(int n){
if(n<=1) return 0;
if(n==2||n==3) return 1;
for(int i=2; i<=n-1; i++)
if(n%i==0) return 0;
return 1;
}
埃氏筛——循环范围缩小 sqrt(n)
int isprime(int n){
if(n<=1) return 0;
if(n==2||n==3) return 1;
for(int i=2; i<=sqrt(n); i++)
if(n%i==0) return 0;
return 1;
}
普通筛法
一开始假设都是素数
从2开始到N,依次判断,如果一个数是素数,那么把他的倍数都标记成不是素数
#include<iostream>
using namespace std;
const int N = 10000;
bool prime[N];
//是素数:true 不是素数:false
void isprime(){
memset(prime,1,sizeof(prime));
for(int i = 2; i<N; i++){
if(prime[i]){
for(int j = 2; j*i<N; j++)
prime[i*j]=0;
}
}
prime[1] = 0;
}
int main(){
isprime();
for(int i=1; i<100; i++)
if(prime[i])
cout << i << " ";
return 0;
}
线性筛法
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
using namespace std;
#define M 10000
int pnum[M+5];
bool prime[M+5];
void isprime(){
int t=1;
//是素数:prime是true 不是:0
memset(prime,1,sizeof(prime));
prime[0] = prime[1] = 0;
for(int i=2; i<=M; i++){
if(prime[i]){
pnum[t++] = i;
}
//乘上系数
for(int j=1; j<=t && i*pnum[j]<=M; j++){
prime[i*pnum[j]]=0;
//prime是这个合数的最小质因子
// i有比prime[j]更小的质因子,或者超出n的范围
if( i % pnum[j]==0 ) break;
}
}
}
int main(){
isprime();
for(int i=0; i<100; i++){
if(prime[i]) cout << i << " ";
}
return 0;
}
避免重复被筛
上面的算法
eg:6 会被2 和3 各筛一次
开一个数组保存目前为止所筛出来的素数,当i被判断是素数,存入,并且把这个数组里所有i倍的数都标记为非素数
I=2:
prime[2]=true;
pnum[0]=2;------t=1
pnum[0]*2 = 4 -> prime[4]=false;
I=3;
prime[3]=true;
pnum[1] = 3;
pnum[0]*3 =6 -> prime[6] = false;
pnum[1]*3 = 9 ->prime[9] = false;
I=4;
prime[4] = false;
pnum[0]*4 = 8 -> prime[8] = false;
pnum[1]*4 = 12 ->prime[12] = false
1 x
2 v
3 v
4x
5
6x
7
8x
9x
10