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