三種素數篩法

【原始篩法】

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;
		}
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章