zoukankan      html  css  js  c++  java
  • 求质数的算法,用筛法得出某数以内的质数

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

  • 相关阅读:
    wikioi 1002 旁路
    OS X升级到10.10使用后pod故障解决方案出现
    Python challenge 3
    maven 编
    独立博客网站FansUnion.cn操作2多年的经验和教训以及未来计划
    Wakelock API详解
    智遥工作流——会签与多人审批区别
    mysql 参数optimizer_switch
    OpenRisc-31-关于在设计具有DMA功能的ipcore时的虚实地址转换问题的分析与解决
    TROUBLE SHOOTING: FRM-30425
  • 原文地址:https://www.cnblogs.com/fidelQuan/p/2271087.html
Copyright © 2011-2022 走看看