sieve method
reference:一般筛法求素数+快速线性筛法求素数
1.naive method
enum k from 2 to √n, if num % k ,then it’s not a prime
2.normal sieve
First, let’s suppose all the nums are prime, from 2 to n. Second, for i=1:num, if this is a prime, then k*prime is not a prime, we can remove k*prime from our set. At last, the set is what we want.
#include <iostream>
#define N 4500
using namespace std;
bool prime[N]={0};
void make_prime(){
memset(prime,1,sizeof(prime));
prime[0]=false;
prime[1]=false; //0 and 1 is not prime
for(int i=2;i<N;i++){
if(prime[i]){ //if this is a prime,then k*prime is not prime
for(int j=i*i;j<N;j+=i){ //i*i because k*i(k<i) has been executed
prime[j]=false;
}
}
}
}
int main(void){
make_prime();
for(int i=1;i<=N;i++){
if(prime[i]){
cout<<i<<' ';
}
}
}
but if we look through this algorithm, it’s easy to find that we remove the same num during the traverse. Hence, we put forward the second algorithm.
3.quick_make_prime
we use two array, one array is to record the prime, and the other is to record nums are not prime. As we know, a composite num can be expressed as prime multiply prime. Hence, we can use the prime we get at present to remove the num that are not primes. By this way, we avoid removing number repeatedly.
#include <iostream>
#define N 4500
using namespace std;
int prime[N]={0},isNotPrime[N]={1,1};
int primeNum=0;
void quick_make_prime(){
for(int i=2;i<N;i++){
if(!isNotPrime[i]){
prime[primeNum++]=i;
}
for(int j=0;j<primeNum&&prime[j]*i<N;j++){
//here we let nums no more than the smallest prime multiply i
isNotPrime[i*prime[j]]=1;
if(!i%prime[j]){
break;
}
}
}
return;
}
int main(void){
quick_make_prime();
for(int i=0;i<primeNum;i++){
cout<<prime[i]<<' ';
}
}