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