您的位置:首页 > 其它

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

2015-06-05 10:16 316 查看
今天看见了一个求质数的问题,闲着无聊就想着实现了一遍,先用传统方法得到输出某数以内的所有质数:如求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:记录下自己的思路与感谢。咱也是程序猿嘛。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: