java求質數的4種方法,


第一種:雙重for循環 使除數與被除數個個計算,效率極低

 public void test1(int n){
        long start = System.currentTimeMillis();    //取開始時間
        int num=0;
        boolean sign;
        for(int i=2;i<n;i++){
            if(i % 2 == 0 && i != 2  )  continue; //偶數和1排除
            sign=true;
            for (int j=2;j<i;j++){
                if(i%j==0){
                    sign=false;
                    break;
                }
            }
            if (sign){
                num++;
       /*         System.out.println(""+i);*/
            }
        }
        System.out.println(n+"以內的素數有"+num+"個");
        long end = System.currentTimeMillis();
        System.out.println("The time cost is " + (end - start));
        System.out.println("");
    }

第二種:主要考慮2 ~ i/2之間的數 ,效率比第一種提高一半

  public void test2(int n){
        long start = System.currentTimeMillis();    //取開始時間
        int num=0;
        int j;
        boolean sgin;
        for (int i = 2; i <= n; i++) {
       
            if(i % 2 == 0 && i != 2  )  continue; //偶數和1排除

            sgin = true;
            for (j = 2; j <= i/2 ; j++) {
                if (i % j == 0) {
                    sgin= false;
                    break;
                }
            }

            //打印
            if (sgin) {
                num++;
               /* System.out.println(""+i);*/
            }
        }
        System.out.println(n+"以內的素數有"+num+"個");
        long end = System.currentTimeMillis();
        System.out.println("The time cost is " + (end - start));
        System.out.println("");
    }

第三種:使用開方去過濾 Math.sqrt(i)

 public void test3(int n){
        long start = System.currentTimeMillis();    //取開始時間
        int num=0;
        int j;
        boolean sgin;
        for (int i = 2; i <= n; i++) {
            if(i % 2 == 0 && i != 2  )  continue; //偶數和1排除

            sgin= true;
            for (j = 2; j <= Math.sqrt(i) ; j++) {
                if (i % j == 0) {
                    sgin = false;
                    break;
                }
            }

            //打印
            if (sgin) {
                num++;
               /* System.out.println(""+i);*/
            }
        }
        System.out.println(n+"以內的素數有"+num+"個");
        long end = System.currentTimeMillis();
        System.out.println("The time cost is " + (end - start));
        System.out.println("");
    }

第四種:逆向思維篩選質素,最為高效

  public void test4(int n){
        long start = System.currentTimeMillis();    //取開始時間
        //素數總和
        int sum = 0;
        //1000萬以內的所有素數
        //用數組將1000萬以內的數分為兩大派系,素數用0代替數值,合數用1代替數值;
        //一開始默認全部為素數,所以值全部為0,等到開始篩選的時候再把為合數的賦值為1
        int num[] = new int[n];
        num[0] = 1;          //由於1規定不是素數,所以要提前用1標值
        //根據埃氏篩法的結論,要得到自然數  N 以內的全部素數,必須把不大於" 二次根號  N "的所有素數的倍數剔除,剩下的就是素數
        double prescription = Math.sqrt(n);
        for (int i = 2; i <= prescription; i++) {
            //開始把所有素數的倍數剔除,剩下的就是素數
            for (int j = i*i; j <= n; j+=i) {
                //從i*i開始去除,因為比i*i小的倍數,已經在前面去除過了
                //例如:i=5
                //5的2倍(10),3倍(15),在i=2的時候,已經去除過了

                num[j-1] = 1;   //把素數的倍數剔除,也就是賦值為1,不是素數就是合數
            }
        }
        //遍歷數組,把值為0的數全部統計出來,得到素數之和
        for (int i = 0; i < num.length; i++) {
            if(num[i]==0)
                sum++;
        }
        System.out.println(n+"以內的素數有"+sum+"個");
        long end = System.currentTimeMillis();
        System.out.println("The time cost is " + (end - start));
        System.out.println("");
    }

 

public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        demo1.test1(100000);
        demo1.test2(100000);
        demo1.test3(100000);
        demo1.test4(100000);
    }

結果:

100000以內的素數有9592個
The time cost is 1558

100000以內的素數有9592個
The time cost is 700

100000以內的素數有9592個
The time cost is 12

100000以內的素數有9592個
The time cost is 4

 備注:感謝前輩們提供的學習資源,前三種來自 :https://blog.csdn.net/u010503822/article/details/78734371 最后一種方式來自:http://how2j.cn/k/number-string/number-string-math/319.html#nowhere

 如有冒犯或者錯誤請多多原諒


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM