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

如何在Java中使用函数来计算质数?

发布时间:2023-05-24 18:34:02

在计算机科学中,质数是一种非常重要的概念。质数是指除了1和本身外没有其他因子的数,例如2、3、5、7等数都是质数。在Java中,我们可以使用函数来计算质数,下面是一些方法。

方法一: 穷举法

穷举法是最简单的方法,它直接从2到n-1遍历每个数,判断它是否为质数。如果它是质数,则把它添加到结果列表中。

public static List<Integer> getPrimes(int n) {

    List<Integer> primes = new ArrayList<Integer>();

    for (int i = 2; i <= n; i++) {

        boolean isPrime = true;

        for (int j = 2; j < i; j++) {

            if (i % j == 0) {

                isPrime = false;

                break;

            }

        }

        if (isPrime) {

            primes.add(i);

        }

    }

    return primes;

}

方法二: 厄拉多塞筛法

厄拉多塞筛法是更高效的方法,它可以在O(nloglogn)时间内找到n以内所有的质数。它的原理是从2开始,将每个质数的倍数标记为合数,直到所有质数的倍数都被标记。因为每个合数都至少有一个质因子,所以对于每个合数i,它的最小质因子都小于等于i的根号。

public static List<Integer> getPrimes(int n) {

    boolean[] isPrime = new boolean[n+1];

    Arrays.fill(isPrime, true);

    for (int i = 2; i * i <= n; i++) {

        if (isPrime[i]) {

            for (int j = i * i; j <= n; j += i) {

                isPrime[j] = false;

            }

        }

    }

    List<Integer> primes = new ArrayList<Integer>();

    for (int i = 2; i <= n; i++) {

        if (isPrime[i]) {

            primes.add(i);

        }

    }

    return primes;

}

方法三: 米勒-拉宾素性测试

米勒-拉宾素性测试是一种概率性算法,它可以快速判断一个数是否是质数。它的原理是利用费马小定理和二次探测法来检测一个数是否是合数。因为它是概率性算法,所以存在可能错误的风险。一般用于大质数的判断。

public static boolean isPrime(long n) {

    if (n < 2) {

        return false;

    }

    if (n != 2 && n % 2 == 0) {

        return false;

    }

    long s = n - 1;

    while (s % 2 == 0) {

        s /= 2;

    }

    Random random = new Random();

    for (int i = 0; i < 5; i++) {

        long a = random.nextLong() % (n - 1) + 1;

        long temp = s;

        long mod = modPow(a, temp, n);

        while (temp != n - 1 && mod != 1 && mod != n - 1) {

            mod = modMultiply(mod, mod, n);

            temp *= 2;

        }

        if (mod != n - 1 && temp % 2 == 0) {

            return false;

        }

    }

    return true;

}

private static long modMultiply(long a, long b, long mod) {

    long ans = 0;

    while (b > 0) {

        if ((b & 1) == 1) {

            ans = (ans + a) % mod;

        }

        a = (a * 2) % mod;

        b >>= 1;

    }

    return ans;

}

private static long modPow(long a, long b, long mod) {

    long ans = 1;

    a %= mod;

    while (b > 0) {

        if ((b & 1) == 1) {

            ans = (ans * a) % mod;

        }

        a = (a * a) % mod;

        b >>= 1;

    }

    return ans;

}

方法四: 梅森素数

梅森素数是指一个数是2的幂次方减1,并且该数本身也是质数,例如3、7、31等数都是梅森素数。在Java中,我们可以利用BigInteger类来计算梅森素数。

public static BigInteger getMersennePrime(int p) {

    return BigInteger.valueOf(2).pow(p).subtract(BigInteger.ONE);

}

public static boolean isMersennePrime(int p) {

    BigInteger mp = getMersennePrime(p);

    return mp.isProbablePrime(100);

}

总结:

在Java中,我们可以使用多种方法来计算质数,从简单的穷举法到更高效的厄拉多塞筛法和概率性算法的米勒-拉宾素性测试,以及特殊的梅森素数计算。在实际应用中,需要根据不同的情况选择合适的方法。