1. 程式人生 > ><<敏捷軟件開發:原則、模式與實踐>>時,素數產生程序,第一個java

<<敏捷軟件開發:原則、模式與實踐>>時,素數產生程序,第一個java

ner ring 部分 跳過 spa urn 輸出 int stat

import java.util.Arrays;


public class GeneratePrimes {


public static void main(String[] args) {

// TODO Auto-generated method stub

int []a =generatePrime(1);

System.out.println(Arrays.toString(a));

}

public static int [] generatePrime(int maxValue){

if(maxValue>=2){

int s = maxValue +1;

boolean[] f = new boolean[s];

int i;

for(i = 0;i<s;i++){

f[i]=true;

}

f[0]=f[1]=false;

int j ;

for (i = 2; i <Math.sqrt(s)+1;i++){

for(j = 2 *i;j<s;j+=i){

f[j]=false;

}

}

int count = 0;

for( i = 0;i<s;i++){

if(f[i]){

count++;

}

}

int [] primes = new int[count];

for(i = 0,j = 0;i<s;i++){

if(f[i]){

primes[j++]=i;

}

}

return primes;

}else{

return new int [0];

}

}

}

在看<<敏捷軟件開發:原則、模式與實踐>>時,素數產生程序,第一個java久把我難了半了,之後找百度搜素數的代碼才知道了篩選法求素數.

首先定義了一個布爾類型的數組,初始值全為通過循環全部置為true,而單獨將0和1置為false,當發現不是素數的時候將對應的下標改為false,然後將只為true的下標作為值賦值給另一個數組然後輸出.(程序是作者故意寫這麽麻煩的為了將重構碼)

重點是中間這個循環想了好久終於想出來為什麽了...

for (i = 2; i <Math.sqrt(s)+1;i++){

for(j = 2 *i;j<s;j+=i){

f[j]=false;

}

}


首先說外層循環怎麽來的

在這之前先說下普通求素數的套路

最笨的辦法就是從2到N-1一個一個暴力的去試.

思考一下其實只要試到2到N/2就好了因為x 如果有(除了自身以外的)質因數,那肯定會小於等於 x/2

在想想除了2以外所有的質因數都是奇數,因此除了2以外試所有的奇數就好了,

在想想會發現因素都是成對出現的比如100,100的因數有:1和100,2和50,4和25,5和20,10和10。想一下,因數肯定一個小於√N一個大於√N.所以只需要試2到√N了.

而這也就是外層循環為什麽for (i = 2; i <Math.sqrt(s)+1;i++)的原因

之後說內層循環,設計到了篩選法

我要尋找從1到15裏的素數 (紅色代表被篩選掉,不是素數)
第1步:1是素數我不用管,不需要篩選掉1的倍數

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

第2步:2沒有被前面的篩選掉,所以2是素數,然後篩選掉2的倍數 4 6 8 10 12 14

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

第3步
:3沒有被前面的篩選掉,那麽3是素數,然後篩選掉3的倍數 6 9 12 15

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

第4步:4被前面的篩選掉了,不是素數,所以跳過此步驟

第5步:5沒有被前面的篩選掉,那麽5是素數,然後篩選掉5的倍數 10 15

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

第6步:6被前面的篩選了,不是素數,所以跳過此步驟

第7步:7沒有被前面的篩選掉,那麽7是素數,然後篩選掉7的倍數 14


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

第8步:8被前面的篩選了,不是素數,所以跳過此步驟

第9步:9被前面的篩選了,不是素數,所以跳過此步驟

第10步:10被前面的篩選了,不是素數,所以跳過此步驟

第11步:11沒有被前面的篩選掉,那麽11是素數,然後篩選掉11的倍數,11的倍數大於15了,沒得篩選

第12步:12被前面的篩選了,不是素數,所以跳過此步驟

第13步:13沒有被前面的篩選掉,那麽13是素數,然後篩選掉13的倍數,13的倍數大於15了,沒得篩選

第14步:14被前面的篩選了,不是素數,所以跳過此步驟

第15步:15被前面的篩選了,不是素數,所以跳過此步驟

所以篩選後的結果中,誰是素數顯而易見了.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
素數是 1 2 3 5 7 11 13

因此內存循環是for(j = 2 *i;j<s;j+=i),2的倍數開始嗎 最小是4.


後面的部分轉載至原出處 https://blog.csdn.net/QQ1910084514/article/details/80157263

<<敏捷軟件開發:原則、模式與實踐>>時,素數產生程序,第一個java