我的Java開發學習之旅------>求N內所有的素數,之旅------
一、素數的概念質數(prime number)又稱素數,有無限個。一個大於1的自然數,除了1和它本身外,不能被其他自然數(質數)整除,換句話說就是該數除了1和它本身以外不再有其他的因數;否則稱為合數。根據算術基本定理,每一個比1大的整數,要麼本身是一個質數,要麼可以寫成一系列質數的乘積;而且如果不考慮這些質數在乘積中的順序,那麼寫出來的形式是唯一的。最小的質數是2
二、演算法演算法1. 開根號法:如果一個數(>2),對這個數求平方根,如果這個數能被這個數的平方根到2之間的任何一個(只要有一個就行)整除說明就不是質數,如果不能就說明是質數!原理:假如一個數N是合數,它有一個約數a,a×b=N,則a、b兩個數中必有一個大於或等於根號N,一個小於或等於根號N。因此,只要小於或等於根號N的數(1除外)不能整除N,則N一定是素數。
public void zhishu(int num) {int i, j, k;for (i = 2; i < num; i++) {k = (int) Math.sqrt(i);for (j = 2; j <= k; j++) {if(i%j==0){break;}}if (j>k) {System.out.println("素數: "+i);}}}
演算法2.埃拉托斯特尼素數篩選法
要得到自然數n以內的全部素數,必須把不大於的所有素數的倍數剔除,剩下的就是素數。給出要篩數值的範圍n,找出以內的素數。先用2去篩,即把2留下,把2的倍數剔除掉;再用下一個質數,也就是3篩,把3留下,把3的倍數剔除掉;接下去用下一個質數5篩,把5留下,把5的倍數剔除掉;不斷重複下去......。步驟詳細列出演算法如下:
- 列出2以後的所有序列:
- 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 標出序列中的第一個素數,也就是2,序列變成:
- 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
- 將剩下序列中,劃掉2的倍數,序列變成:
- 2 3 5 7 9 11 13 15 17 19 21 23 25
- 如果現在這個序列中最大數小於最後一個標出的素數的平方,那麼剩下的序列中所有的數都是素數,否則回到第二步。
- 本例中,因為25大於2的平方,我們返回第二步:
- 剩下的序列中第一個素數是3,將主序列中3的倍數劃掉,主序列變成:
- 2 3 5 7 11 13 17 19 23 25
- 我們得到的素數有:2,3
- 25仍然大於3的平方,所以我們還要返回第二步:
- 現在序列中第一個素數是5,同樣將序列中5的倍數劃掉,主序列成了:
- 我們得到的素數有:2,3,5 。
- 因為23小於5的平方,跳出迴圈.
結論:2到25之間的素數是:2 3 5 7 11 13 17 19 23。
下面代碼摘自網路
public static void getPrimes(int n) {if (n < 2 || n > 9999999) // 之所以限制最大值為9999999萬,是因為JVM記憶體限制,當然有其他靈活方案可以繞過(比如位元影像法)throw new IllegalArgumentException("輸入參數n錯誤!");int[] array = new int[n]; // 假設初始所有數都是素數,且某個數是素數,則其值為0;比如第一個數為素數那麼array[0]為0array[0] = 1; // 0不是素數array[1] = 1; // 1不是素數// 下面是篩選核心過程for (int i = 2; i < Math.sqrt(n); i++) { // 從最小素數2開始if (array[i] == 0) {for (int j = i * i; j < n; j += i) {array[j] = 1; // 標識該位置為非素數}}}// 列印n以內的所有素數,每排10個輸出System.out.println(n + "以內的素數如下: ");int count = 0; // 當前已經輸出的素數個數int rowLength = 10; // 每行輸出的素數個數for (int i = 0; i < array.length; i++) {if (array[i] == 0) {if (count % rowLength == 0 && count != 0) {System.out.println();}count++;System.out.print(i + "\t");}}}
用以上兩個演算法求9999999的所有素數開根號法用時:21507毫秒埃拉托斯特尼素數篩選法用時: 6658毫秒
關於演算法,以下幾個用C實現的先mark下來。
http://blog.chinaunix.net/uid-26548237-id-3364131.html
超高速計算n以內素數個數(百億內3毫秒解決)http://blog.csdn.net/jianxia_wzx/article/details/8663759
==================================================================================================
作者:歐陽鵬 歡迎轉載,與人分享是進步的源泉!
轉載請保留原文地址:http://blog.csdn.net/ouyang_peng
==================================================================================================