欢迎访问宙启技术站
智能推送

在Java中如何使用函数来判断一个数字是否是质数

发布时间:2023-06-06 22:10:07

在Java中,判断一个数字是否为质数的方法有很多种,下面介绍几种常见的方法。

方法一:暴力枚举法

暴力枚举法是最简单、最直接的判断一个数字是否为质数的方法。其基本思路是,从2开始到n-1,逐个判断n除以每个数的余数,如果一个余数为0,则n不是质数,否则n是质数。

具体代码实现如下:

public static boolean isPrime(int n) {
    if (n < 2) {
        return false;
    }
    for (int i = 2; i < n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

方法二:优化枚举法

在暴力枚举法的基础上,可以进行一些优化,比如只需要枚举到n的平方根就可以了。因为如果n有一个大于平方根的因数,那么一定会有一个小于平方根的因数。同时,由于1不是质数,可以先判断n是否为1。

具体代码实现如下:

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

方法三:埃氏筛法

埃氏筛法是一种比较高效的判断质数的方法,其基本思路是,先将所有数字标记为质数,然后从2开始,将其所有的倍数标记为合数,直到没有剩余的未标记的数字为止。

具体代码实现如下:

public static boolean isPrime(int n) {
    if (n < 2) {
        return false;
    }
    boolean[] isPrime = new boolean[n + 1];
    Arrays.fill(isPrime, true);
    for (int i = 2; i <= Math.sqrt(n); i++) {
        if (isPrime[i]) {
            for (int j = i * i; j <= n; j += i) {
                isPrime[j] = false;
            }
        }
    }
    return isPrime[n];
}

方法四:米勒-拉宾素数测试

米勒-拉宾素数测试是一种比较高级的质数判断方法,其基本思路是利用费马小定理,对于一个大于1的质数p,有a^(p-1)modp=1。假设p是合数,那么假设p-1=2^r * d,则有a^d * (a^(2^r))^d * (a^(2^r))^d * ... * (a^(2^(r-1)))^d * (a^(2^(r-1)))^d * ... * (a^2)^d * a^d mod p = a^(2^(r-1)*d)modp ≠ 1。

根据这个性质,可以随机取一个数a,判断其是否满足这个性质。如果满足,那么p很可能是质数,否则就是合数。需要进行多次随机测试才能保证结果的正确性。

具体代码实现如下:

public static boolean isPrime(int n) {
    if (n <= 2) {
        return n == 2;
    }
    if (n % 2 == 0) {
        return false;
    }
    int r = n - 1;
    int d = 0;
    while (r % 2 == 0) {
        r /= 2;
        d++;
    }
    for (int i = 0; i < 5; i++) {
        int a = (int) (Math.random() * (n - 2) + 2);
        int x = fastPow(a, r, n);
        boolean isWitness = false;
        if (x != 1 && x != n - 1) {
            for (int j = 0; j < d; j++) {
                x = (int) ((long) x * x % n);
                if (x == n - 1) {
                    isWitness = true;
                    break;
                }
            }
            if (!isWitness) {
                return false;
            }
        }
    }
    return true;
}
 
private static int fastPow(int a, int b, int p) {
    int res = 1 % p;
    while (b > 0) {
        if ((b & 1) == 1) {
            res = (int) ((long) res * a % p);
        }
        a = (int) ((long) a * a % p);
        b >>= 1;
    }
    return res;
}

以上就是四种常见的判断质数的方法。需要注意的是,当判断的数字比较大时, 种方法会非常慢,第二种和第三种方法相对比较快,而第四种方法则是最快的。