這些零碎的知識點每個都學過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;