美文网首页
判断一个数是否是质数的算法

判断一个数是否是质数的算法

作者: d3f59bfc7013 | 来源:发表于2018-06-21 15:26 被阅读0次

对于一个大于1的整数,如果其除数只有1和它本身,那么它就是一个质数

判断一个数是否为质数

穷举法

  • 穷举法,检测2,3,4,5...,n-1能够整除n。如果不能,那么n就是素数。这个算法耗费O(n)来检测n是否是一个素数。
public static boolean isPrimeNumber(int n){
        if (n < 2) {
            return false;
        }
        for (int i = 2; i <= n-1; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

时间复杂度为O(n)

稍微改进的算法

  • 稍微注意一下,只需检测2,3,4,5...n/2是否能整除n。如果不能那么n就是素数。算法效率只是稍微提高了一点,它的时间复杂度依旧是O(n)
public static boolean isPrimeNumber1(int n) {
        if (n < 2) {
            return false;
        }
        for (int i = 2; i <= n / 2; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

高效算法

  • 实际上我们可以证明,如果n不是素数,那么n必须有一个大于1且小于或者等于√n。证明过程:
    因为n不是素数,所以会存在两个数p和q,满足n=pq且1<p≤q。注意到n=√n*√n。p必须小于等于√n。

    因此只需要检测2,3,4,5,...,√n是否能被n整除。如果不能,n就是素数。这会显著的降低时间复杂度,为O(√n)。

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

上述开根号的效率较低,可以用以下方式代替。

public static boolean isPrimeNumber3(int n) {
        if (n < 2) {
            return false;
        }
        int squareRoot=1;
        while(squareRoot*squareRoot<n){
            squareRoot++;
        }
        for (int i = 2; i  <= squareRoot; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

筛选出小于n内所有质数的

上述都是判断一个大于1的自然数是否是素数的算法,对于筛选出小于自然数n内的所有素数,有一个更为高效的算法,埃拉托斯特尼筛法。这个算法求出所有小于或等于n的素数。

这个算法的原理是:一个质数总是可以分解成若干个质数的乘积,那么如果把质数(最初只知道2是质数)的倍数都去掉,那么剩下的就是质数了。

埃拉托斯特尼筛法

算法实现:

/**
     * 运用埃拉托色筛选法筛选出所有小于等于n的质数
     */
    public static boolean[] sieveOfEratosthenes(int n) {
        boolean[] isPrime = new boolean[n + 1];
        //初始化,默认所有都是质数
        for (int i = 0; i <= n; i++) {
            isPrime[i] = true;
        }
        //筛选,将所有质数的倍数都标记为非质数(最初只知道2是质数)
        for (int i = 2; i <= n / i; i++) {
            if (isPrime[i]) {
                for (int j = 2; j <= n/i; j++) {
                    isPrime[i * j] = false;
                }
            }
        }
        return isPrime;
    }

给出总的程序代码:

/**
 * @author: gethin
 * @create: 2018-06-20 21:40
 * @description:
 **/
public class PrimeNumberJudge {
    
    /**
     * 穷举法判断是否为质数,时间复杂度O(n)
     */
    public static boolean isPrimeNumber(int n) {
        if (n < 2) {
            return false;
        }
        for (int i = 2; i <= n - 1; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 穷举法稍微改进,时间复杂度O(n)
     */
    public static boolean isPrimeNumber1(int n) {
        if (n < 2) {
            return false;
        }
        for (int i = 2; i <= n / 2; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 高效算法,时间复杂度O(√n)
     */
    public static boolean isPrimeNumber2(int n) {
        if (n < 2) {
            return false;
        }
        int squareRoot = (int) Math.sqrt(n);
        for (int i = 2; i <= squareRoot; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 高效算法改进,时间复杂度O(√n)
     */
    public static boolean isPrimeNumber3(int n) {
        if (n < 2) {
            return false;
        }
        int squareRoot = 1;
        while (squareRoot * squareRoot < n) {
            squareRoot++;
        }
        for (int i = 2; i <= squareRoot; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * 运用埃拉托色筛选法筛选出所有小于等于n的质数
     */
    public static boolean[] sieveOfEratosthenes(int n) {
        boolean[] isPrime = new boolean[n + 1];
        //初始化,默认所有都是质数
        for (int i = 0; i <= n; i++) {
            isPrime[i] = true;
        }
        //筛选,将所有质数的倍数都标记为非质数(最初只知道2是质数)
        for (int i = 2; i <= n / i; i++) {
            if (isPrime[i]) {
                for (int j = 2; j <= n / i; j++) {
                    isPrime[i * j] = false;
                }
            }
        }
        return isPrime;
    }
    
    public static void main(String[] args) {
        int count = 0;
        Scanner input = new Scanner(System.in);
        System.out.print("输入整数n:");
        int num = input.nextInt();
        System.out.println("\n运用改进的高效算法求小于等于n的所有质数");
        for (int i = 0; i <= num; i++) {
            if (isPrimeNumber1(i)) {
                if (count % 10 == 0) {
                    System.out.println();
                }
                System.out.print(i + "\t");
                count++;
            }
        }
        System.out.println("\n\n运用埃拉托色筛选法求小于等于n的所有质数");
        boolean[] isPrime = sieveOfEratosthenes(num);
        count=0;
        for (int i = 2; i <= num; i++) {
            if (isPrime[i]) {
                if (count % 10 == 0) {
                    System.out.println();
                }
                System.out.print(i + "\t");
                count++;
            }
        }
    }
}

相关文章

  • 2019-09-03

    判断一个数是否是质数 求出1-100 范围内的质数

  • 《Python高性能编程》札记1_判断质数

    判断一个数是否为质数:

  • 如何快速的判断一个数是否是质数?

    任意的一个数,你如何能判断它是否是质数呢?我们学过的235的倍数的特点,就该想到如何判断一个数是否是质数 只要是2...

  • 判断一个数是否是质数的算法

    对于一个大于1的整数,如果其除数只有1和它本身,那么它就是一个质数 判断一个数是否为质数 穷举法 穷举法,检测2,...

  • 数学知识

    一、数论 首先需要掌握质数的定义,判断一个数是否是质数的试除法、Miller–Rabin等。学习筛法,求出1~N之...

  • 筛选质数

    关于怎么判断一个数 n 是否是质数,最简单的方法是枚举 2 到 n−1,判断是否是 n 的约数。如果是, n 肯定...

  • 素数(质数)筛选法模板

    判断一个数是否为质数 素数筛选法(时间复杂度O(nlogn))

  • 判断一个数是否是质数

    质数大于 1 查看因子 for i in range(2,num): (不懂) 如果输入的数字小于或等于 1,...

  • 2019-03-23 函数的使用方法

    isNaN() 函数,用于检查其参数是否是非数字值 实例: isNaN() 判断一个数字是质数 instanc...

  • 常用算法

    求最大公约数 判断字符串是否为回文串 判断数字是否为质数 判断数组中是否存在相同元素 求阶乘 二进制中1的个数

网友评论

      本文标题:判断一个数是否是质数的算法

      本文链接:https://www.haomeiwen.com/subject/luzqyftx.html