面试题:求[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;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值