Java經典案例之用三種方法求1~100以內素數之和


素數,不能被除了1和本身以外整除的數被稱為素數。接下來我用三種方式求得1~100以內素數。

方式一

外層每循環一次,內層就計算出這個數有幾個因子,我們都知道素數的因子只有兩個,所以如果個數為2就加進總和里面:

package day_11_25;

/** * 計算1-100之間的素數和 * * @author soberw */

public class PrimeFor {
    public static void main(String[] args) {
        //記錄和
        int sum = 0;
        //記錄因子個數
        int count = 0;
        int counter = 0;
        for (int i = 2; i <= 100; i++) {
            //初始置0
            count = 0;
            for (int j = 1; j <= i; j++) {
                counter++;
                if (i % j == 0) {
                    count++;
                }
            }
            //兩個因子為素數
            if (count == 2) {
                sum += i;
            }

        }
        System.out.println("總和為" + sum);
        System.out.println("循環了" + counter + "次");
    }

}

運行結果:
在這里插入圖片描述
共計算了5049次。

方式二

方式一雖然好理解,但是也存在很多的問題,比如如果一個數他本來就是偶數(當然除了2),那就沒有判斷的必要了,也還有就是沒有中斷條件,就算已經知道了這個數不是素數了,但程序還是從頭到尾循環了一遍,於是我做了改進,加入了互斥鎖,並且從2開始計算(因為最小素數為2),實現如下:

package day_11_25;

/** * 計算1-100之間的素數和 * * @author soberw */

public class PrimeFor2 {
    public static void main(String[] args) {
        int sum = 0;
        //聲明互斥鎖
        boolean flag = true;
        int counter = 0;
        for (int i = 2; i <= 100; i++) {
            flag = true;
            //偶數直接跳到下一次
            if (i != 2 && i % 2 == 0){
                continue;
            }
            //從2到除了它本身的數之間判斷
            for (int j = 2; j < i; j++) {
                counter++;
                //有因子直接退出
                if (i % j == 0) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                sum += i;
            }
        }
        System.out.println("總和為" + sum);
        System.out.println("循環了" + counter + "次");
    }

}

運行結果:
在這里插入圖片描述

相比於第一種方法確實快了不少,共計算了1084次。

方式三

那么有沒有更好的方法呢,答案是肯定的,我們在判斷的時候,都是從頭到尾去循環一遍,就算是加了互斥鎖,也要一次加一個去判斷,有點繁瑣。
那有沒有更好的解決方式呢,於是我就想到了下面這種方法,通過開平方判斷。打個比方,如果我們要判斷100是不是素數,就首先確定一個中間數,你可以找到100的根(10),將數分成兩份,如圖:
在這里插入圖片描述
圖可能畫的有點抽象,其實就是我們將10作為中間數,10前面的數乘以10后面的數如果有出現等於100的情況,那就不是素數(比如2x50=100)。
因為因子都是成對存在的,1和100,2和50,4和25,5和20,10和10。成對的因子,其中一個必然小於等於100的開平方,另一個大於等於100的開平方。所以這樣一來我們就最多判斷10次就行了,一下子減少了90次。效率成倍提高。而且實現起來也不復雜,如下:

package day_11_25;

/** * 計算1-100之間的素數和 * * @author soberw */

public class PrimeFor3 {
    public static void main(String[] args) {
        int sum = 0;
        int counter = 0;
        label:
        for (int i = 2; i <= 100; i++) {
            if (i != 2 && i % 2 == 0) {
                continue;
            }
            for (int j = 2; j <= Math.sqrt(i); j++) {
                counter++;
                if (i % j == 0) {
                    continue label;
                }
            }
            sum += i;
        }
        System.out.println(sum);
        System.out.println(counter);
    }

}

運行結果:
在這里插入圖片描述
僅僅計算了187次,相比於前兩種方法,大大的提高了效率。


免責聲明!

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



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