求質數的算法,用篩法得出某數以內的質數

今天看見了一個求質數的問題,閒着無聊就想着實現了一遍,先用傳統方法得到輸出某數以內的所有質數:如求1000以內的所有質數,

和輸入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:記錄下自己的思路與感謝。咱也是程序猿嘛。。。。

發佈了18 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章