和輸入100,即得到大於自然數1的100個質數。哈哈,也算複習了下數學知識啦。
現在貼下幾種實現方法的代碼:
1、輸入某數,即得到大於自然數1的多少個質數:
1 /** 2 * 質數集合 3 */ 4 static Set<Integer> primeNumSet = new HashSet<Integer>(); 5 6 7 /** 8 * 檢查是否合數 9 * @param number 10 * @return 11 */ 12 public static boolean checkIsComposite(int number){ 13 Iterator<Integer> num = primeNumSet.iterator(); 14 while (num.hasNext()) { 15 if(number%num.next() == 0){ 16 return true; 17 } 18 } 19 return false; 20 } 21 22 /** 23 * 得到numberCount個大於自然數1的質數 24 * @param numberCount 25 */ 26 public static void getPrimeNumByCount(int numberCount){ 27 for (int i = 2; true; i++) { 28 //檢查是否是合數 29 if (checkIsComposite(i)) { 30 continue; 31 } 32 33 primeNumSet.add(i); 34 if (primeNumSet.size()>=numberCount) { 35 return; 36 } 37 } 38 } 39 40 41 42 /** 43 * 打印 44 */ 45 public static void print(){ 46 //排序 47 List<Integer> tempSort =new ArrayList<Integer>(); 48 tempSort.addAll(primeNumSet); 49 50 //輸出 51 Collections.sort(tempSort); 52 Iterator<Integer> prime=tempSort.iterator(); 53 54 int i=1; 55 while (prime.hasNext()) { 56 System.out.print(prime.next()+"\t"); 57 58 //換行 59 if (i%10==0) { 60 System.out.print("\n"); 61 } 62 i++; 63 } 64 } 65 66 public static void main(String[] args) { 67 double beginTime = System.currentTimeMillis(); 68 69 try { 70 71 getPrimeNumByCount(10000); 72 73 74 } catch (Exception e) { 75 e.printStackTrace(); 76 } 77 78 double endTime = System.currentTimeMillis(); 79 80 print(); 81 82 double numCount = 0; 83 84 numCount = primeNumSet.size(); 85 86 System.out.println("\n輸出完畢!總計"+numCount+"個質數,耗時:"+String.valueOf((endTime-beginTime)/1000)+"秒"); 87 88 89 }
2、得到並輸出某數以內的所有質數:
1 /** 2 * 質數集合 3 */ 4 private static Set<Integer> primeNumSet = new HashSet<Integer>(); 5 6 /** 7 * 檢查是否合數 8 * @param number 9 * @return 10 */ 11 private static boolean checkIsComposite(int number){ 12 Iterator<Integer> num = primeNumSet.iterator(); 13 while (num.hasNext()) { 14 if(number%num.next() == 0){ 15 return true; 16 } 17 } 18 return false; 19 } 20 21 /** 22 * 得到maxNum以內的質數 23 * @param maxNum 24 */ 25 public static void getPrimeNumByMaxNum(int maxNum){ 26 27 double beginTime = System.currentTimeMillis(); 28 29 30 for (int i = 2; i<=maxNum; i++) { 31 //檢查是否是合數 32 if (checkIsComposite(i)) { 33 continue; 34 } 35 36 primeNumSet.add(i); 37 38 } 39 40 double endTime = System.currentTimeMillis(); 41 42 print(); 43 44 double numCount = 0; 45 46 numCount = primeNumSet.size(); 47 48 System.out.println("\n輸出完畢!總計"+numCount+"個質數,耗時:"+String.valueOf((endTime-beginTime)/1000)+"秒"); 49 } 50 51 52 53 /** 54 * 打印 55 */ 56 private static void print(){ 57 //排序 58 List<Integer> tempSort =new ArrayList<Integer>(); 59 tempSort.addAll(primeNumSet); 60 61 //輸出 62 Collections.sort(tempSort); 63 Iterator<Integer> prime=tempSort.iterator(); 64 65 int i=1; 66 while (prime.hasNext()) { 67 System.out.print(prime.next()+"\t"); 68 69 //換行 70 if (i%10==0) { 71 System.out.print("\n"); 72 } 73 i++; 74 } 75 } 76 77 public static void main(String[] args) { 78 getPrimeNumByMaxNum(1000); 79 }
3、用篩法算法得到某數以內的所有質數(最佳):
1 /** 2 * 質數集合 3 */ 4 static Set<Integer> primeNumSet = new HashSet<Integer>(); 5 6 /** 7 * 合數集合 8 */ 9 static Set<Integer> compositeNumSet = new HashSet<Integer>(); 10 11 12 /** 13 * 得到maxNum以內的質數(篩法) 14 * @param maxNum 15 */ 16 public static void getPrimeNumByMaxNumOfSieve(int maxNum){ 17 18 for (int i = 2; i<=maxNum; i++) { 19 20 if (!compositeNumSet.contains(i)) { 21 primeNumSet.add(i); 22 filterMultiple(i, maxNum); 23 } 24 } 25 } 26 27 28 /** 29 * 篩除maxNum以內baseNum倍數,添加到合數集合 30 * @param maxNum 31 */ 32 public static void filterMultiple(int baseNum,int maxNum){ 33 for (int i = 2; true; i++) { 34 if(baseNum * i <= maxNum){ 35 36 compositeNumSet.add(baseNum * i); 37 38 }else{ 39 break; 40 } 41 } 42 43 } 44 45 /** 46 * 打印 47 */ 48 public static void print(){ 49 //排序 50 List<Integer> tempSort =new ArrayList<Integer>(); 51 tempSort.addAll(primeNumSet); 52 53 //輸出 54 Collections.sort(tempSort); 55 Iterator<Integer> prime=tempSort.iterator(); 56 57 int i=1; 58 while (prime.hasNext()) { 59 System.out.print(prime.next()+"\t"); 60 61 //換行 62 if (i%10==0) { 63 System.out.print("\n"); 64 } 65 i++; 66 } 67 } 68 69 public static void main(String[] args) { 70 double beginTime = System.currentTimeMillis(); 71 72 try { 73 74 getPrimeNumByMaxNumOfSieve(150000); 75 76 } catch (Exception e) { 77 e.printStackTrace(); 78 } 79 80 double endTime = System.currentTimeMillis(); 81 82 print(); 83 84 double numCount = 0; 85 86 numCount = primeNumSet.size(); 87 88 System.out.println("\n輸出完畢!總計"+numCount+"個質數,耗時:"+String.valueOf((endTime-beginTime)/1000)+"秒"); 89 90 91 }
暫時就研究出這幾種。。
對比了下三種方法,用第三種(篩法)效率明顯比前兩種快好幾倍,而且隨着輸入參數的增大,效率與之成正比。
但是這三種算法都有一個bug,即輸入參數不能過大,已經測試的是在1000000左右是極限,超過這個數字會報 內存溢出 異常,
這個還有待改進,後面有嘗試用分頁的思路存儲質數和合數,可以實現效果,但是效率大打折扣。
應該還有更好的方法,嘗試中.....
ps:記錄下自己的思路與感謝。咱也是程序猿嘛。。。。