面试题:求[2, n)之间的素数个数

题目:求[2, n)之间的素数个数
素数的定义:
素数是指大于1的自然数,除了1和它本身之外没有其他因数的数。也就是说,素数只能被1和它本身整除,不能被其他自然数整除。

解法1
最简单的实现思路是,实现素数判断函数,然后从2~n逐个判断,然后统计素数个数

public static int countPrimes(int n) {
        if(2== n){
            return 1;
        }
        int count =0;
        for(int i=2;i<n;i++){
            if(isPrime(i)){
                count++;
            }
        }
        return count;
    }
 
    public static Boolean isPrime(int n) {
        for(int i=2;i<n;i++){
            if(0 == n%i){
                return Boolean.FALSE;
            }
        }
        System.out.println("prime=" + n);
        return Boolean.TRUE;
    }

  

解法2

        观察非素数的特点,如6为非素数,它除了被1和6本身整除外,6=2*3=3*2 ,所以实际上述判断时我们判断i<sqrt[n]即可,则算法改造如下:

 public static int countPrimes_2(int n) {
        if(2== n){
            return 1;
        }
        int count =0;
        for(int i=2;i<n;i++){
            if(isPrime_2(i)){
                count++;
            }
        }
        return count;
    }
    public static Boolean isPrime_2(int n) {
        for(int i=2;i*i<=n;i++){
            if(0 == n%i){
                return Boolean.FALSE;
            }
        }
        System.out.println("prime=" + n);
        return Boolean.TRUE;
    }

  

解法3:

        再观察一下素数的整数倍,都不是素数,比如2*2=4,2*3=6,2*4=8,2*5=10...都不是

则看可以改造算法如下:初始化所有元素都是素数,然后按照素数的整数倍不是素数赋值,然后再统计素数个数

 public static int countPrimes_3(int n) {
        Boolean[] isPrimes = new Boolean[n];
        Arrays.fill(isPrimes,Boolean.TRUE);
        for(int i=2;i<n;i++){
            if(isPrimes[i]){
                for(int j=2*i;j<n;j+=i){
                    isPrimes[j] = false;
                }
            }
        }
        int count =0;
        for(int i=2;i<n;i++){
            if(isPrimes[i]){
                count++;
            }
        }
        return count;
    }

  

解法4

        结合2,3结论,i只要到sqrt[n]即可,而6=2*3=3*2是对称的,最终优化的算法如下

public static int countPrimes_4(int n) {
        Boolean[] isPrimes = new Boolean[n];
        Arrays.fill(isPrimes,Boolean.TRUE);
        for(int i=2;i*i<n;i++){
            if(isPrimes[i]){
                for(int j=i*i;j<n;j+=i){
                    isPrimes[j] = false;
                }
            }
        }
        int count =0;
        for(int i=2;i<n;i++){
            if(isPrimes[i]){
                count++;
            }
        }
        return count;
    }

  

posted @ 2024-08-21 12:34  life_start  阅读(4)  评论(0编辑  收藏  举报