【原始篩法】
void isprime1(int n) {
for(int i=2; i<=sqrt(n); i++)
if(n%i==0) return false;
return true;
}
【普通篩——埃拉託斯特尼(Eratosthenes)篩法】(又稱埃氏篩法)
bool is_prime[MAX+5];//標記是否爲素數
int prime[MAX/2];//存放素數
int cnt=0;//已存放的素數個數
void isprime2() {
memset(is_prime,true,sizeof is_prime);
for(int i=2; i<=MAX; i++) {
if(is_prime[i]) {
prime[cnt++]=i;
for(int j=i+i; j<=MAX; j+=i) //二次篩選法:i是素數,則i的倍數必不爲素數,篩掉
is_prime[j]=false;
}
}
}
【線性篩——歐拉Euler篩】
prime[]數組中的素數是遞增的,當i%prime[j]==0,那麼i*prime[j+1]這個合數肯定被prime[j]乘以某個數篩掉。因爲i中含有因子prime[j],prime[j]比prime[j+1]小,即i=k*prime[j],那麼i*prime[j+1]=(k*prime[j])*prime[j+1]=k*(prime[j]*prime[j+1]),接下去的素數同理。所以不用篩下去了。因此,在滿足i%prime[j]==0這個條件之前以及第一次滿足改條件時,prime[j]必定是prime[j]*i的最小因子。
bool is_prime[MAX+5];
void isprime3() {
int is_prime[MAX+5];
int i,j,cnt=0;
memset(is_prime,true,sizeof(is_prime));
for(i=2; i<=MAX; i++) {
if(is_prime[i])
prime[cnt++]=i;
for(j=0; j<cnt&&prime[j]*i<=MAX; j++) {
is_prime[prime[j]*i]=false;
if(i%prime[j]==0) //保證每個合數只會被它的最小質因數篩去,因此每個數只會被標記一次
break;
}
}
}