短时间求素数 java

        这是我的第二篇文章,我的想法是把自己再学习的路上遇到的困难都给记录下来,一来是方便以后的自我复习,二来就是大家资源共享,帮助和我一样遇到困难的小伙伴们。

         素数又称质数。

        首先,我们来看一下素数(质数)的定义:一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做素数;

   第一种   看到这里我们就可以用一种 列举 的方法判断它是否为素数。

        1到100以内的素数如下表:

  

               思路最清晰,但是速度最慢,在某些oj上可能会超时。

        原理就是让这个数n%(2 3 4 5 6······n-1)然后判断是否为0

        如果再取余的过程中有只要存在一个成立的话,那这个数就不是质数。

        代码如下:


import java.util.Scanner;
public class Tast01 {
public static void main(String[] args) {
	Scanner arr=new Scanner(System .in );
	int n=arr.nextInt();
	boolean a=false;					//用于记录
	for (int i = 2; i <n; i++) {		//除 2--n-1
		if(n%i==0) {
			System.out.println("不是质数");
			a=true;						
			break;						//结束循环,防止输出多个“不是素数”
		}
	}
	if(a==false) {						
		System.out.println("是质数");
	}
	
}
}

     第二种:与上面类似,原理就是让这个数n%(2 3 4 5 6······根号n)然后判断是否为0

              这里比较难以理解,大家看下图就可以知道了。

                                                   

         也就是说,300除到15理论上就可以清楚哪些数据可以整除了。所以我们让n%(2 3 4 5 6······根号n)然后判断是否为0。    根号n=Math.sqrt(n)

        这里要注意:调用Math.sqrt()这一函数的时候时间上也是有不少的消耗品的,所以我们可以将 i<n变为  i*i<n,但是i*i如果太大可能会超出int 的范围,所以这里我们将int i转为long i。

        还可以在此基础上做修改  n%( 3  5 7 9 11 13 ······根号n)将i++变为i+=2  需要单独判断一下2,这一数字.

代码如下:


import java.util.Scanner;
public class Tast03 {
public static void main(String[] args) {
	Scanner arr=new Scanner(System .in );
	int n=arr.nextInt();
	boolean a=false;					//用于记录
	if(n==2) {
		System.out.println("不是质数");
	}
	for (long i = 3; i*i <n; i+=2) {		//除 2--n-1
		if(n%i==0) {
			System.out.println("不是质数");
			a=true;				
			break;						//结束循环,防止输出多个“不是素数”
		}
	}
	if(a==false) {						
		System.out.println("是质数");
	}
	
}
}

     第三种:标准的爱拉托逊斯筛选法-------本段截取        素数判断的几种方法代码实现及其复杂度分析 - 百度文库
        爱拉托逊斯筛选法(以下简称筛法)是一种高效的判断素数的方法。能够一次性的筛选出某个区间的素数。其算法原理本质还是充分利用了素数的定义,即素数的约数只有1和它本身。如果某个数m是另一个数n的倍数,则说明m肯定不是素数。所以我们只要在某个范围内,将已知素数的所有倍数都筛去,剩下的肯定是素数。因为只有它不是其他数的倍数(1和本身除外)具体做法是:先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。因为希腊人是把数写在涂腊的板上,每要划去一个数,就在上面记以小点,寻求质数的工作完毕后,这许多小点就像一个筛子,所以就把埃拉托斯特尼的方法叫做“埃拉托斯特尼筛”,简称“筛法”。(另一种解释是当时的数写在纸草上,每要划去一个数,就把这个数挖去,寻求质数的工作完毕后,这许多小洞就像一个筛子。)

                

	public class Tast04 {
	    public static void main(String[] args) {
	        int max = 1000000000;
	      Tast04 pn = new Tast04();
	        pn.sieveOfEratosthenes(max);
	    }
	    
	    boolean[] sieveOfEratosthenes(int max){
	        boolean[] flags = new boolean[max+1];
	        int count = 0;//统计一共有多少个素数
	        int prime = 2;
	        //初始化,设置flags数组全部为true
	        for (int i = 0; i < max; i++) {
	            flags[i] = true;
	        }
	        flags[0] = flags[1] = false;

	        while (prime <= max) {
	            //剔除prime的倍数
	            crossOff(flags, prime);
	            //找出下一个为true的值
	            prime = getNextPrime(flags, prime);
	            if (prime >= flags.length) {
	                break;
	            }
	            count++;
	            System.out.println("prime = "+prime);
	        }
	        System.out.println("count = "+count);

	        return flags;
	    }
	    void crossOff(boolean[] flags,int prime){
	        /*
	         * 剔除余下的prime倍数的数字,从prime*prime开始,因为如果k*prime且k<prime,
	         * 在之前的迭代中已经被剔除了
	         */
	        for (int i = prime*prime; i < flags.length; i+=prime) {
	            flags[i] =false;
	        }
	    }
	    int getNextPrime(boolean[] flags,int prime){
	        int next = prime + 1;
	        while (next < flags.length && !flags[next]) {
	            next++;
	        }
	        return next;
	    }
	
}

            谢谢大家!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值