求质数常见的几种方法

一、最简单的方法

  1. 从2到n-1进行遍历

对n进行质数判断,质数的定义为该数除了1和其本身在无其他的因数。因此对n进行除i操作,i的范围为2到n-1,如果可以除尽,则表示n除了1和其本身还有其他的因数,因此n不是质数,返回false,如果在除以i的时候并没有除尽的操作,则返回true。

public boolean method1(String [] args){
  int n=10;
  for(int i=2;i<n;i++){
      if(n%i==0)
         return false;
   }
  return true;
} 
  1. 从2到n/2

上面的方法思想简单,但是效率比较低,很多数会重复进行除操作,所以将i的范围缩小到2--n/2,可以提高效率。

public boolean method2(String [] args){
  int n=10;
  for(int i=2;i<=n/2;i++){
      if(n%i==0)
         return false;
   }
  return true;
} 
  1. 从2到Math.sqrt(n)进行遍历

该方法和上面的方法的意图是相同的,该方法将i的范围缩小到2---Math.sqrt(n)

public boolean method3(String [] args){
  int n=10;
  for(int i=2;i<=Math.sqrt(n);i++)
  //for(int i=2;i*i<=n;i++)  //和上一行的代码意思相同
  {
      if(n%i==0)
         return false;
   }
  return true;
} 

第一种方法思想简单,但是效率不高,尤其是在求n以内的质数这种题上。

二、埃及筛

认真看喽,本文重点来啦

1、概念:

一个素数的整数倍必定为合数

2、算法的思想

1、创建一个长度为n+1的数组prim; //我当时一直想不明白为什么要创建一个n+1长度的数组,判断的数为n,难道不应该创建数组的长度为n吗?(不知道有没有人和我一样呢?哈哈哈)

后来我才想明白因为数组的下标是从0,开始的,若n=10,你创建一个长度为n的数组,数组是从0--9的,并不包含10。

2、初始化prim数组的所有元素都为1,即默认所有的数都是质数;

3、进入for循环,进行判断;此时范围为for(int i=2;i<=n;i++);// i从2开始,是因为数组中下标为0的数用不上,下标为1的数是用来表示数字1的,而1不是质数,所以要从数字2进行判断;

4、在for循环中,如果prim[i]==1(i为质数),则将i的所有整数倍置为合数。此时本来是要对所有的i(质数)都要进行整数倍置为合数的操作,但是这样不仅效率比较低,而且越往后置为合数的数越少,所以这里让i只到Math.sqrt(n); 对i进行整数倍置为合数操作的时候,本应该 2i 3i 4i......都要置为合数的,但是有些数在之前的i-1已经操作过,所以此时不必在进行操作,我们只需要从i*i开始即可。举个例子

i=2,prim[i]==1---->if(i*i<=n)---->4 6 8 10都置为合数

i=3,prim[i]==1---->if(i*i<=n)----->6 9置为合数,可此时6已经操作过了,所以我们应从i*i开始操作

3、代码

public boolean method4(){
  int n=10;
  int [] prim=new int[n+1];//创建一个长度为n+1的数组
  Arrays.fill(prim,1);//初始化所有的数都为质数,用1表示为质数,0表示为合数
  //Arrays.fill(int [],int val)函数:将指定的 int 值分配给指定 int 型数组的每个元素
  for(int i=2;i<=n;i++){
     if(prim[i]==1){ //如果i为合数
        if(i*i<=n)    //对i到MAth.sqrt(i)进行判断
            for(int j=i*i;j<=n;j+=i)  //从i*i开始进行置为合数操作,步长为i
                prim[j]=0; 
     }
  }
  return prim[n]==1?true:false;
}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值