试除法、朴素筛法、线性筛法求质数

一、试除法

求一个数是否是质数,遍历就行

二、朴素筛法

求2~n中有多少个数是质数

        一个合数必定能分解为, 一个质数乘以 一个质数/合数。所以我们将 2~n 的所有质数 的倍数删掉,那么这个数组的所有合数就被删除了,剩下的就是质数。

三、线性筛法

求2~n中有多少个数是质数

        线性筛法 求2~n中有多少个质数,朴素筛法 有冗余的筛除,而线性筛法就是解决掉了,这问题,它的思想就是,用一个数的最小质数去筛掉该数,就不会导致重复筛一个数


四、代码

package cource.nemberTheory;

import java.util.Arrays;

/**
 * @Auther: duanYL
 * @Date: 2023/10/17/9:17
 * @Description:
 */
public class Prime {
    public static void main(String[] args) {
        System.out.println(isPrime(20));
        getPrimes(20);
        obtainPrimes(20);
    }

    /**
     * 试除法求单个质数
     */
    public static boolean isPrime(int target) {
        if (target < 2)
            return false;
        /*  这里不建议使用i*i,可能会越界.
            也不建议使用Math.sqrt(target),直接除,编译器可以优化
         */
        for (int i = 2; i <= target / i; i++) {
            if (target % i == 0)
                return false;
        }
        return true;
    }

    /**
     * 朴素筛法求 2~n中有多少个质数
     * 一个合数必定能分解为 一个质数乘以 一个质数/合数
     * 所以我们将 2~n 的所有质数 的倍数删掉
     * 那么这个数组的所有合数就被删除了
     * 剩下的就是质数
     *
     * @param n
     */
    public static void getPrimes(int n) {
        int count = 0; //记录有多少个素数
        int[] primes = new int[n + 1];    //记录素数
        /*
            boolean数组默认值为false,为false为质数,true为合数
         */
        boolean[] st = new boolean[n + 1];
        for (int i = 2; i <= n; i++) {
            if (st[i])
                continue;
            primes[count++] = i;
            /* 第二个循环不难看出会有 冗余的筛除
               当i为2时,st[2]=true,st[4]=true,st[6]=true
               当i为3时,st[3]=true,st[6]=true
               st[6]重复筛了一次
             */
            for (int j = i; j <= n; j += i) {     //将当前质数的所有倍数筛除
                st[j] = true;
            }
        }
        System.out.println(Arrays.toString(Arrays.copyOf(primes, count)));
    }

    /**
     * 线性筛法 求2~n中有多少个质数
     * 朴素筛法 有冗余的筛除,而线性筛法就是解决掉了,这问题
     * 它的思想就是,用一个数的最小质数去筛掉该数,就不会导致重复筛一个数
     *
     * @param n
     */
    public static void obtainPrimes(int n) {
        int count = 0; //记录有多少个素数
        int[] primes = new int[n];
        boolean[] st = new boolean[n + 1];  //为false为质数,true为合数
        for (int i = 2; i <= n; i++) {
            if (!st[i])     //如果是质数则记录
                primes[count++] = i;
            for (int j = 0; primes[j] <= n / i; j++) {
                st[primes[j] * i] = true;   //primes[j]是primes[j] * i的最小的质数
                if (i % primes[j] == 0)
                    break;
            }
        }
        System.out.println(Arrays.toString(Arrays.copyOf(primes, count)));
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值