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

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

原文地址:https://www.cnblogs.com/fidelQuan/p/2271087.html