如何用 Java 判斷一個給定的數是不是素數

有關素數的定義:質數又稱素數。一個大於1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做質數;否則稱爲合數(規定1既不是質數也不是合數)。

生成素數的算法

在我們論壇中我們給出了一個有關素數生成算法。

這個是一個公司的面試題目,請參考 Prime numbers from 1 to 100 (打印 100 以內的素數) 頁面中的內容。

如何判斷一個數是不是素數

爲什麼要判斷一個數是不是素數?因爲質數 非常重要,隨之數字越來越大,那麼在計算時候的時間複雜度越來越高,因此我們需要快速判斷一個數是不是質數。

這個問題你可能需要了解下 米勒-拉賓檢驗( Miller–Rabin primality test) 這個東西。

米勒-拉賓素性檢驗是一種素數判定法則,利用隨機化算法判斷一個數是合數還是可能是素數。卡內基梅隆大學的計算機系教授Gary Lee Miller首先提出了基於廣義黎曼猜想的確定性算法,由於廣義黎曼猜想並沒有被證明,其後由以色列耶路撒冷希伯來大學的Michael O. Rabin教授作出修改,提出了不依賴於該假設的隨機化算法。

Java 原生

下面的代碼是 Java 原生代碼解決的方法。

        Boolean isPrime = number > 1
                && IntStream.rangeClosed(2, (int) Math.sqrt(number))
                .noneMatch(n -> (number % n == 0));

上面的代碼使用了IntStream,並且使用數學的 Math 來進行計算。

上面的代碼不太好讀,可能你大部分時候都不會這麼去寫。

BigInteger 方法

我們可以使用 BigInteger 的 isProbablePrime 方法來近似判斷。

這個近似判斷就使用了 米勒-拉賓素性檢驗。

在面試的時候,使用這個方法就可以了,因爲有時候一些 online 的 code 平臺不會提供第三方的工具讓你使用。

int number = 10;
BigInteger.valueOf(number).isProbablePrime(100);

Apache Math3

這個方法就非常簡單了,直接用就可以了。

也是所有方法中檢驗效果最好,速度最快的。

int number = 10;
Primes.isPrime(number)

爲什麼呢?這是因爲 Apache 的 Commons Math3 使用了一個數組,把一定範圍內的素數都列出來了。

簡單粗暴,所以效率最高。

 

2021-09-23_15-43-26

 

範圍就是 Java 整數不溢出的情況下進行判斷的。

結論

素數可能會經常用到,尤其在隨機數算法的時候。

同時又因爲算法無法覆蓋掉所有的素數,因此很多公司面試的時候都會喜歡用這個題目來爲難你。

完整的代碼如下:

    @Test
    public void testIsPrime() {
        int number = 10;
        Boolean isPrime = number > 1
                && IntStream.rangeClosed(2, (int) Math.sqrt(number))
                .noneMatch(n -> (number % n == 0));

        logger.debug(" {} Prime CORE Check is - [{}]", number, isPrime);
        logger.debug(" {} Prime BigInteger Check is - [{}]", number, BigInteger.valueOf(number).isProbablePrime(100));
        logger.debug(" {} Prime APACHE MATH3 Check is - [{}]", number, Primes.isPrime(number));
    }

上面測試代碼的輸出結果爲:

15:37:02.403 [main] DEBUG com.ossez.toolkits.codebank.tests.algorithm.PrimeNumbersTest -  10 Prime CORE Check is - [false]
15:37:02.406 [main] DEBUG com.ossez.toolkits.codebank.tests.algorithm.PrimeNumbersTest -  10 Prime BigInteger Check is - [false]
15:37:02.411 [main] DEBUG com.ossez.toolkits.codebank.tests.algorithm.PrimeNumbersTest -  10 Prime APACHE MATH3 Check is - [false]

Process finished with exit code 0

其實我們這樣看,是不是簡單粗暴就是最好的呢?

 

https://www.ossez.com/t/java/13749

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章