判断 一个数 是不是 质数 / 素数

判断 一个数 是不是 质数 / 素数

【面试必备 100题 系列 】- 001 - 判断 一个数 是不是 质数 / 素数

一、命题分析:

   质数 又称 素数。指整数在一个大于1的 自然数 中,除了1和此整数自身外,没法被其他自然数整除的数。换句话说,只有两个正因数(1和自己)的自然数即为素数。比1大但不是素数的数称为 合数 。1和0既非素数也非合数。素数在 数论中有着很重要的作用。

二、答案解析:

1、简洁、低效方案:

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


    首先,过滤一下小于等于 3 的数,因为小于等于3的自然数只有 2 和 3 是质数/ 素数。

    然后,我们只需要从 2 开始,一直到小于其自身,依次判断能否被 n 整除即可,能够整除则不是质数/ 素数,否则是质数/ 素数。

2、优化方案:
   

假设 n 是合数,必然存在 非1 的两个约数 p1 p2,其中 p1<=sqrt(n)p2>=sqrt(n)

由此我们可以改进上述方法优化循环次数。如下:

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

3、最优方案:
    质数还有一个不为人知的特性:                           

/**
 * 恒等于 6x-1 或者 6x+1,其中 x 是大于等于1的自然数
 */

    基于这个理论我们不难推算出:

        a、能被 6 整除的,肯定不是质数/ 素数,可以肯定的是,6x 不是质数/ 素数;

        b、能被  2 / 3 整除的,肯定不是 质数/ 素数, 因此,6x+2 / 6x+3/ 6x+4  肯定也不是质数/ 素数;

那么,就剩下 6x+16x+5 (即等同于6x-1) 可能是质数/ 素数了。

得出方案:循环的步长可以设为 6,每次只判断 6 前后的两个数即可。

public static boolean isPrime(int num) {
    if (num <= 3) {
        return num > 1;
    }
    // 不在6的倍数两侧的一定不是质数
    if (num % 6 != 1 && num % 6 != 5) {
        return false;
    }
    int sqrt = (int) Math.sqrt(num);
    for (int i = 5; i <= sqrt; i += 6) {
        if (num % i == 0 || num % (i + 2) == 0) {
            return false;
        }
    }
    return true;
}


 

发布了46 篇原创文章 · 获赞 74 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/MLQ8087/article/details/103732397