1. 程式人生 > 其它 >騷操作,利用正則表示式判斷素數!!!

騷操作,利用正則表示式判斷素數!!!

技術標籤:java演算法素數篩

利用正則判斷素數

判斷素數有很多方法, 比如定義法,費馬小定理,米勒-拉賓素性檢驗,Solovay-Strassen素性判定等。

一、定義法

這種方法利用素數定義來判斷素數。
素數又叫質數,質數是指在大於1的自然數中,除了1和它本身以外,不能被其他自然數整除的數。最小的質數是2,它也是唯一的偶數質數,最前面的質數依次排列為:2、3、5、7、11、13、17、19、23、29、31等。

static boolean isPrime(int n) {
        if (n <= 1)
            return false;
        else
if (n == 2) return true; else if (n % 2 == 0) return false; for (int i = 3; i <= Math.sqrt(n); i += 2) { if (n % i == 0) return false; } return true; }

二、費馬小定理

費馬小定理(Fermat’s little theorem)是數論中的一個重要定理,在1636年提出。如果p是一個質數對於任意a, 1 < a < n − 1 1 < a < n-1

1<a<n1 滿足
a n − 1 ≡ 1 ( m o d n ) a^{n-1}\equiv1(mod\ n) an11(modn) 或者 a n − 1 a^{n-1} an1 % n = 1 n=1 n=1

static int power(int a, int n, int p) {
        int res = 1;
        a = a % p;
        while (n > 0) {
            if ((n & 1) == 1) res = (res * a) % p;

            n = n >>
1; // n = n/2 a = (a * a) % p; } return res; } static boolean isPrime(int n, int k) { if (n <= 1 || n == 4) return false; if (n <= 3) return true; while (k > 0) { int a = 2 + (int) (Math.random() % (n - 4)); if (power(a, n - 1, n) != 1) return false; k--; } return true; }

三、利用正則判斷素數

 public static void main(String[] args) {

        System.err.println(prime(0));
        // false
        System.err.println(prime(1));
        // true
        System.err.println(prime(2));
        // true
        System.err.println(prime(3));
        // true
        System.err.println(prime(5));
        // false
        System.err.println(prime(8));
        // true
        System.err.println(prime(13));
        // false
        System.err.println(prime(14));
        // false
        System.err.println(prime(15));
    }

    public static boolean prime(int n) {
        return !new String(new char[n]).matches(".?|(..+?)\\1+");
    }

改演算法的精髓在 !new String(new char[n]).matches(".?|(..+?)\\1+");這行程式碼。
該函式首先生成n個字元,並嘗試檢視該字串是否匹配".?|(..+?)\\1+"。如果n是素數,則matches函式會返回false,然後再將結果反轉。
表示式的第一部分.? 是確保1不是素數。因為n等於1或者0的話,String的長度為1或者0,那麼.?會匹配上,經過返回false。最重要的地方在表示式的第二部分括號括起來的部分。(..+?)以非貪婪模式方式匹配至少兩個字元,然後\\1反向引用(..+?)匹配到的部分,再利用+匹配至少一次。
根據定義,素數是一個大於1的自然數,除了1和它本身沒有正因子。這意味著如果 a = n × m a=n\times m a=n×m,那麼a不是素數。 n × m n\times m n×m可以進一步解釋n個字元重複m次”,這便是正則表示式的原理。使用(..+?)匹配n個字元長度,然後使用\\1重複m次。