素數判定,素數篩

這些零碎的知識點每個都學過N次了,但隔一段時間就會忘,記錄下來

素數定義:只能被自身和1整除的大於1的正整數
通過這個定義,我們就可以得出判斷素數的

  • 第一種方法:
    將這個素數除以從 (2,sqrt(n)] 的數,若沒有整除的就是素數(這裏所用的最大除數是sqrt(n)而不是n-1的原因是:現在正過來想,num1*num2 = n,那當試到num1>sqrt(n)的情況時,num2一定就<sqrt(n)那這種情況已經排除過了,就相當於重複計算)
    這樣時間複雜度是O(sqrt(n))

這裏用到了cmath中的sqrt函數,其原型爲double sqrt(double);
所以在取上界的時候,爲了避免double帶來的精度丟失,寧可多枚舉一個也不能少一個,bound = (int)sqrt(n)+1;

bool isPrime(int x)
{
	if(x<=1) return false;
	int bound = (int)sqrt(x)+1;
	for(int i = 2;i<=bound;i++)
	{
		if(x%i==0) return false;
	}
	return true;
}

但上述方法判斷某個數是素數的複雜度還可以,但要是判斷從1到n的所有數是否爲素數,那就複雜度太高了O(n*sqrt(n))

  • 第二種方法:
    前面是得到某個數是素數就完了,沒有充分利用這個信息
    得到一個素數之後,就可以把求解範圍內的所有是它倍數的數都去掉,當判斷到某個數是不是素數的時候,已經把所有比它小的數的倍數都去掉了,那它一定是素數
#define maxn ...
bool isPrime[maxn];
void judge(void)
{
	memset(isPrime,true,sizeof(isPrime));
	isPrime[1] = false;
	int bound = (int)sqrt(maxn)+1;
	for(int i = 2;i<=bound;i++)
	{
		if(isPrime[i])
			for(j = i;j*i<=maxn;j++) isPrime[j*i] = false; //並不需要從2*i就開始標記,因爲k*i(k<i)一定在k的因數時就被標記過了 
	}	
}

//把素數放在一個數組中,並且可以求有多少個
int prime[maxn]; 
int sum = 0;
for(int i = 1;i<=maxn;i++) 
	if(isPrime[i]) prime[sum++] = i;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章