day4 力扣 11.22 素数个数统计

题目类型素数个数统计

题目要求: 统计n以内的素数个数

public class PrimeNumber1 {

    public static void main(String[] args) {
        //打印100以内的素数个数(预计结果为25)
        System.out.println("暴力算法统计素数个数为"+bf(100));
        //测试结果确实为25
    }

    /**
     * 使用暴力算法统计素数个数
     * @param n 统计素数边界值
     * @return 返回int型的素数个数
     */
    public static int bf(int n) {
        //统计素数个数的计数器
        int count = 0;
        //外层for循环遍历(其时间复杂度为n)
        for (int i = 2; i < n; i++) {
            //使用三元运算符: 判断数字i是否为素数, 若是素数(值为false), count值加1, 否则保持不变
//            count += isPrime(i) ? 1 : 0;
            //算法改进后进行素数判断
            count += isPrime2(i) ? 1 : 0;
        }
       return count;
    }

    /**
     * 判断当前数字是否为素数 原版
     * @param x 整型自然数
     * @return 布尔型值true或者false
     */
    private static boolean isPrime(int x) {
        //内层for循环遍历(其时间复杂度为x)
        for (int i = 2; i < x; i++) {
            //判断x是否为素数(即判断x是否能够被i整除)
            if(x % i == 0) {
                //若能被整除, 则返回false
                return false;
            }
        }
        //若不能被整除, 则返回true
        return true;
    }

    /**
     * 判断当前数字是否为素数 改进版
     * 在第一版基础上降低算法时间复杂度
     * @param x 整型数字
     * @return 布尔型值true或者false
     */
    private static boolean isPrime2(int x) {

        /**
         * 问题: 使用暴力算法时, 总的时间复杂度为n+x, 执行效率太低
         * 改进思路:
         * i的取值范围其实没必要取到x, 实际上只需要取到根号下x即可;
         *
         * 为什么取到根号下x就可以了呢?
         * 假设x值为12, 那么12能被整除的组合因子有哪些呢?
         * 包括: 1*12 2*6 3*4 4*3 6*2 12*1
         * 我们发现, 前面三个跟后面三个的关系只是两个因子位置颠倒,
         * 也就是满足乘法交换律, 只要能被前三个组合中的两个因子整除,
         * 也一定能被后三个组合中的两个因子整除, 因此取到根号下x即可;
         * 这样不仅可以减少for循环次数, 而且时间复杂度也随之降低
         */

        //内层for循环遍历
//        for (int i = 2; i < x; i++) {
        //方式一: 使用Math.sqrt()函数开根号
        for (int i = 2; i <= Math.sqrt(x); i++) {
            //方式二: 使用i * i < x表示(作用相当于x开根号)
//          for (int i = 2; i * i <= x; i++) {
            //判断x是否为素数(即判断x是否能够被i整除)
            if(x % i == 0) {
                //若能被整除, 则返回false
                return false;
            }
        }
        //若不能被整除, 则返回true
        return true;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值