我的Java開發學習之旅------>求N內所有的素數,之旅------

來源:互聯網
上載者:User

我的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的倍數剔除掉;不斷重複下去......。步驟詳細列出演算法如下:
  1. 列出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,序列變成:
    • 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  3. 將剩下序列中,劃掉2的倍數,序列變成:
    • 2 3 5 7 9 11 13 15 17 19 21 23 25
  4. 如果現在這個序列中最大數小於最後一個標出的素數的平方,那麼剩下的序列中所有的數都是素數,否則回到第二步。
  5. 本例中,因為25大於2的平方,我們返回第二步:
  6. 剩下的序列中第一個素數是3,將主序列中3的倍數劃掉,主序列變成:
    • 2 3 5 7 11 13 17 19 23 25
  7. 我們得到的素數有:2,3
  8. 25仍然大於3的平方,所以我們還要返回第二步:
  9. 現在序列中第一個素數是5,同樣將序列中5的倍數劃掉,主序列成了:
    • 2 3 5 7 11 13 17 19 23
  10. 我們得到的素數有:2,3,5 。
  11. 因為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

==================================================================================================



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.