有關素數的定義:質數又稱素數。一個大於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 使用了一個數組,把一定范圍內的素數都列出來了。
簡單粗暴,所以效率最高。
范圍就是 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
其實我們這樣看,是不是簡單粗暴就是最好的呢?