〖数学算法〗素性测试

所谓素性测试是检测一个数是否为素数的测试。而对素数的研究是有很长一段历史,把素数的东西写成一本书的话也许得上千页,而现代密码学又加深了科研工作者对素数的研究,今天就以输出100以内的素数的为例,讲讲素性测试的几种方法。


1.试除法

这可能是每个学过计算机的朋友都敲过的代码,原理就是从判断2sqrt(n)或者n/2能不能整除n,若能整除就不是素数。

代码清单:

public class SuXingCeShi {

	public static void main(String[] args) {
		
		int n = 100;
		SuXingCeShi robot = new SuXingCeShi();
		robot.shichu(n);
		
	}

	private void shichu(int n) {
		
		for(int i = 2; i <= n; i++){
			int j;
			for(j = 2; j < Math.sqrt(i); j++){
				if(i % j == 0)
					break;
			}
		if(j > Math.sqrt(i))
			System.out.print(i + " ");

		}
		
		System.out.println();	
	}
}

2.eratosthenes筛选法(埃拉托斯特尼筛法

步骤:

1.列出2,3,4..........100

2.选取第一个没被处理过的数(第一次为2)

3.去掉以2为因数的所有数

4.如果下一个素数小于sqrt(100)跳转到第二步

5.结束

以下是来至wikipedia介绍该算法的图片,挺直观的,可以看看


代码清单:

public class SuXingCeShi {

	public static void main(String[] args) {
		
		int n = 100;
		SuXingCeShi robot = new SuXingCeShi();
		robot.eratosthenesShaixuan(n);
		
	}
	public void eratosthenesShaixuan(int n) {
		// TODO Auto-generated method stub
		int[] a = new int[n+1];//申请n+1个空间
		a[0] = a[1] = -1;//剔除0,1
		for(int i = 2; i < n+1; i++)
			a[i] = i; 
		
		int temp = 2;
		double edge = Math.sqrt(n);//边界值
		while(temp <= edge){
			if(a[temp] == -1){//如果a[temp]是合数
				temp++;
				continue;
			}
			//如果a[temp]是质素,去掉以它为因数的合数
			for(int i = 2; i <= (a.length-1)/temp ; i++){
				a[temp*i] = -1;
			}
			temp++;
		}
		for(int i = 0; i < a.length; i++){
			if(a[i] != -1)
				System.out.print(a[i] + " ");
		}
		System.out.println();
	}
}

3.一种更快的筛选算法

eratosthenes算法在拆选的时候进行了重复拆选,比如数302、3、5都对其进行了拆选,有没有一种更好的方法,让每个合数只被拆选一次呢?

这个算法稍稍有些难理解,先看代码

public class SuXingCeShi {

	public static void main(String[] args) {
		
		int n = 100;
		SuXingCeShi robot = new SuXingCeShi();
		robot.caixuan(n);
		
	}
	void caixuan(int n){
		 boolean flag[] = new boolean[n+1];
		 int prime[] = new int[n+1];
	     int prime_num = 0;
	     for(int i=0; i<=n; i++){
	         flag[i] = true;//把所有数都看成素数
	     }
	     for(int i = 2; i <= n; i++){
	         if(flag[i] == true){
	        	 prime[prime_num++] = i;//记录素数
	         }
	         for(int j=0; j <prime_num && prime[j]*i <= n; j++){
	             flag[prime[j]*i] = false;//把合数赋值成false
	             if(i % prime[j] == 0)
	                 
  • 22
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值