素数判断以及素数筛法(附上Java例题代码以及解释)

尽量以浅显的语言去描述一个方法,恳请各位批评指正!

单个素数判断:

例题1:输入一个数字n,判断n是否为素数。

/**
 * 最朴素的素数判断(需要明白素数的定义)
 * 定义:一个只能被1和它本身整除的数是素数
 * 例:数字7 只能被1和7整除 所以:7是素数
 *
 * @param n
 * @return
 */
public static boolean isPrime01(int n) {
    if (n < 2) return false;
    else if (n == 2) return true;//2是素数
    else {
        for (int i = 2; i < n; i++) {//遍历 2 到 n-1
            if (n % i == 0) return false;
        }
        return true;
    }
}

/**
 * 较为优化的素数判断:
 * 当一个数不能被小于等于他开平方的数整除时,必然为素数
 * 例子:9 开平方是3 依次判断1 2 3 我们得知9可以整除3 所以9 不是素数
 * @param n
 * @return
 */
public static boolean isPrime02(int n)
{
    if(n<2) return false;
    else if(n==2) return true;
    else{
        for(int i=2;i*i<=n;i++)//不用数学函数sqrt的话,就这么写
        {
            if(n%i==0) return false;
        }
        return true;
    }
}
//另外还有费马小定理判别素数的方式,这个基本上用不到,需要的可以自行研究学习
//此处只提供方式
/*
* 当然!还有更为暴力的方式就是,自己选择一个容器事先存好一定范围的素数,直接判断。
* 比如:利用数组,建立一个bool类型的数组,以数组下标为数字,以相应下标对应的值为素数标志。
*    num[0]=false num[1]=false num[2]=true............
* */
}

素数筛法

筛法一(埃氏筛法):

当我们遇到以下情况时候,总不能多次调用判断函数吧,这样会增加程序复杂度。这时就需要用到素数筛法:
情景一:当一个程序要判断多个不同的数字是否为素数时
情景二:当要判断给定的一个范围内有多少个素数时

    .

例题2 :从键盘多次输入整数n,判断其是否为素数。(2<n<100)当输入为-1时,程序结束。

 public static void main(String[] args) {

   /*
   这里我们建立一个bool类型的数组,以下标为要判断的数字 以该下标的值为素数的标志
   若i是素数 则 isPrime[i]=false
   (这里刚好跟我们理解的相反哈! 是素数是false 不是反而是true 因为这样方便点! )
   * */
    boolean [] isPrime = new boolean[101];

    //核心就一句话:素数的倍数一定不是素数
    //第一趟 我们把2的倍速全砍掉
    //第二趟 我们把3的倍数全砍掉
    //第三趟 我们把5的倍数全砍掉
    //...
    ///...
    //剩下的就全是素数了
    isPrime[0]=isPrime[1]=true;
    for(int i=2 ;i<101;i++){
        if(!isPrime[i])//判断当前数是否为素数
        for(int j=i+i;j<101;j+=i){
            isPrime[j]=true;
        }
    }
/*这样采用了一种事先打表的方式,罗列的范围内的所有素数
* 在程序运行时 能更快做出判断
* */
}

筛法一其实仍有不足之处,比如说6 这个数字 。 我们在砍去2的倍数的时候 以及砍去3的倍数的时候
给6进行了两次赋值,也就是说筛到了两遍!这样导致了不必要的一些操作,浪费资源。 在介绍筛法二之前,大家需要先明白。每个合数都必然有素数因子。
比如:合数12 有素数因子2 3 、合数14 有素数因子2 7 而且一个数n的最大质因子不会超过这个数开平方(也就是根号n)

所以便有了第二种筛法!

筛法二(欧拉筛法):

    public static void main(String[] args) {

    boolean[] isPrime = new boolean[101];
    isPrime[0] = isPrime[1] = true;
    int[] Prime = new int[100];//存放素数的数组
    int t = 0;
    Prime[t++] = 2;//把2放进素数表
    for (int i = 2; i < 100; i++) {
        if (!isPrime[i])//若当前数是素数
            Prime[t++] = i;//则存入素数数组
        for (int j = 0; j < t && Prime[j] * i < 100; j++) {
            isPrime[i * Prime[j]] = true;
            if (i % Prime[j] == 0) break;//避免重筛(核心)
        }
    }
    for (int i = 0; i < 100; i++) {
        System.out.println(i + " " + isPrime[i]);
    }
}
/*这样避免了方法一的重复晒同一个数,使得程序更有效率*/
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值