質數是只能被1或者自身整除的自然數(不包括1),稱為質數。
判斷是否是質數最直觀和簡單的方法就是從2開始直接除,能除盡(餘數為0)就不是質數。則c語言實現為:
int isprime(int m)
該演算法的時間複雜度o(n)。
可以改進一下,根據如果乙個數是合數,那麼它的最小質因數肯定小於等於它的平方根
。用反證法可以證明一下。假設x是n的最小質因數,則存在n/x=p。p>x,x*p=n。如果x不小於等於它的平方根,則x*x>n,而p>x,故x*p>n,假設不成立。合數是與質數相對應的自然數。乙個大於1的自然數如果它不是合數,則它是質數。也就是說
如果乙個數能被它的最小質因數整除的話,那它肯定是合數,即
不是質數。所以判斷乙個數是否是質數,只需判斷它是否能被小於它開跟號後的所有數整除,因此,這樣做的運算少了很多,降低了時間複雜度。c語言實現
int isprime(int m)
時間複雜度o(根號n)
上面兩種方法是最常見的。如果要判斷乙個範圍內的數是否是質數,則需要多次呼叫isprime()函式,時間複雜度變為增加o(n*m)或o(n*跟號m).這時,可以採用另一種稱為「埃拉託色尼(eratosthenes)
篩法」的方法。埃拉託色尼
是古希臘的著名數學家。他採取的方法是,在一張紙上寫上1到100全部整數,然後逐個判斷它們是否是素數,找出乙個非素數,就把它挖掉,最後剩下的就是素數。
具體做法如下:
<1> 先將1挖掉(因為1不是素數)。
<2> 用2去除它後面的各個數,把能被2整除的數挖掉,即把2的倍數挖掉。
<3> 用3去除它後面的各數,把3的倍數挖掉。
<4> 分別用4、5…各數作為除數去除這些數以後的各數。這個過程一直進行到在除數後面的數已全被挖掉為止。
如上演算法可表示為:
<1> 挖去1;
<2> 用剛才被挖去的數的下乙個數p去除p後面各數,把p的倍數挖掉;
<3> 檢查p是否小於n^2的整數部分(如果n=1000, 則檢查p<31?),如果是,則返回(2)繼續執行,否則就結束;
<4> 紙上剩下的數就是素數。
這是個典型的用空間換時間的演算法。
#include
#include
#include
int main() /*初始化陣列*/
a[1] = 0; /*1不是質數*/
for (i=2; ifor(i=1,n=0; i<=100; i++)
}} /*輸出a[i]不為0的數(即質數)*/
printf("\n");
return 0;
}
判斷乙個數是否是質數
乙個數如果可以進行因數分解,那麼分解的兩個數一定是乙個小於等於sqrt n 乙個大於等於sqrt n 因此遍歷到sqrt n 即可。因為如果sqrt n 左側找不到因數,右側也一定找不到因數。中心思想 遍歷n是否能被2到sqrt n 之間的數整除,如果不能則為質數。import math defis...
演算法小練習 判斷乙個數是否是質數
第一種常規方法 var isprime function num 查表直接返回的素數 var pmap return dmap num false pmap num true num 5 false num 1 6 true num 1 6 true false 第二種方法 var isprime ...
JS判斷乙個數是否為質數
非正則實現function isprime num 因為2是比較特殊的質數,所以先拿出來 if num 2 else if num 2 0 依次判斷是否能被奇數整除,最大迴圈為數值的開方 let squareroot math.sqrt num 因為2已經驗證過,所以從3開始 且已經排除偶數,所以每...