判斷質數的幾種方法

2022-03-27 04:14:40 字數 3397 閱讀 3958

根據維基百科定義,質數(prime number),又稱素數,指在大於1的自然數中,除了1和此整數自身外,無法被其他自然數整除的數(也可定義為只有1和本身兩個因數的數)。比1大但不是素數的數稱為合數。

1和0既非素數也非合數。

質數在公鑰加密演算法(如rsa)中有重要的地位。

下邊將會介紹幾種較為常見的判斷質/素數的方法:

法一是按照質數的定義來考慮的,具體程式見下:

1

//*********************************** method 1 ***********************************//2

bool isprime::isprime_1(uint

num)312

}1314return

ret;

15 }

對於乙個正整數num而言,它對(num/2, num)範圍內的正整數是必然不能夠整除的,因此,我們在判斷num的時候,沒有必要讓它除以該範圍內的數。**如下:

1

//*********************************** method 2 ***********************************//2

bool isprime::isprime_2(uint

num)313

}1415return

ret;

16 }

對於乙個小於num的正整數x,如果num不能整除x,則num必然不能整除num/x (num = num/x * x)。反之相同。我們又知num =√num*√num。 如果n除以大於√num的數,必得到小於√num的商,而小於√num的整數已經在2到√num的整數試過了,因為就沒有必要再試(√num, num)範圍內的數了。**如下:

注:經常會看到別人說「乙個數 n 如果是合數,那麼它的所有的因子不超過sqrt(n)」。這句話是錯誤的。舉乙個例子,16的因子包括了1、2、4、8,但很明顯8>√16。另外,因子跟因數是不一樣的,因數還會包括數本身,如16的因數為1、2、4、8、16。

1

//*********************************** method 3 ***********************************//2

bool isprime::isprime_3(uint

num)313

}1415return

ret;

16 }

我們都知道,除了2之外,其他所有的偶數(正整數)全都不是質數,因為它們都能被2整除。**改進如下:

1

//*********************************** method 4 ***********************************//2

bool isprime::isprime_4(uint

num)319

}20}21

else

2225

26return

ret;

27 }

當我們判斷某個取值範圍內的素數有哪些的時候,有乙個方法非常可行,就是埃拉託斯特尼篩選法。這個演算法效率很高,但占用空間較大。

我們知道,乙個素數p只有1和p這兩個約數,並且它的約數一定不大於其本身。因此,我們下邊方法來篩選出來素數:

1)把從2開始的、某一範圍內的正整數從小到大順序排列;

2)剩下的數中選擇最小的素數,然後去掉它的倍數。

3)依次類推,直到迴圈結束。

這種篩選法動態圖如下:

程式如下:

1

//*********************************** method 5 ***********************************//2

//find prime numbers between [lower bound, upper bound)

3 vector isprime::retprime_5(uint lbound, uint

ubound)419

}2021 vectorret;

22for (int i = lbound; i < ubound; i++)

2327

28return

ret;

29 }

對於法五來說,即使isprime中已經被判斷為false的元素,它以及它的倍數還會被重新賦值為false(可能會有很多遍),而實際上已經沒有必要這樣子做。例如,第2個元素的倍數第4、6、8、10...個元素已經被判定為false,但迴圈到第4個元素的時候,第8、12、16...個元素還會被重新賦值,這有點重複。因此,我們要去掉這些重複的工作。**比較簡單,只需要加一語句即可,見下:

1

//*********************************** method 6 ***********************************//2

//find prime numbers between [lower bound, upper bound)

3 vector isprime::retprime_6(uint lbound, uint

ubound)417

18for (int i = 2; i < ubound; i++)

1926}27

}2829 vectorret;

30for (int i = lbound; i < ubound; i++)

3135

36return

ret;

37 }

法七是結合了法三及法六,**如下:

1

//*********************************** method 7 ***********************************//2

//find prime numbers between [lower bound, upper bound)

3 vector isprime::retprime_7(uint lbound, uint

ubound)417

18uint ulimit = sqrt(ubound) + 1;19

for (int i = 2; i < ulimit; i++)

2028}29

}3031 vectorret;

32for (int i = lbound; i < ubound; i++)

3337

38return

ret;

39 }

整個程式**(包括單元測試**)見github.

Java求素數(質數)的幾種方法

比1大的整數中,除了1和它本身以外,不再有別的因數,這種整數叫做質數或素數 要判斷x是否為質數,就從2一直嘗試到x 1的做法效率是最差的!其實只要從2一直嘗試到 x,就可以了。因為因數都是成對出現的。比如,100的因數有 1和100,2和50,4和25,5和20,10和10。看出來沒有?成對的因數,...

《質數》判斷質數(較快的方法C )

to be honest,我感覺我也刷了1,200道題了,真是有的題刷了一次又一次,但是還是存在會的還是會,不會的還是不會。因而我就思考是不是我的做題模式出現了問題。下面展示一下我之前的做題風格,哎,還是走高三的老路,就是刷題,不總結,不分類,只追求數量。為了改善這種情況,我決定做好總結與分類,以求...

判斷是否是陣列的幾種方法

判斷objectname是否是陣列 基本資料型別也可以使用此方法。123 constructor number true1 2判斷有誤差。a 在不同 iframe 中建立的 array 並不共享 prototype b 即使為true,也有可能不是陣列。function subarray subar...