求质数的算法,用筛法得出某数以内的质数

今天看见了一个求质数的问题,闲着无聊就想着实现了一遍,先用传统方法得到输出某数以内的所有质数:如求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:记录下自己的思路与感谢。咱也是程序猿嘛。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值