判断1-100质数(素数)

文章介绍了质数的定义,以及三种不同的算法来判断质数:基本方法、埃式筛法和欧拉筛法。基本方法对每个数字进行判断,埃式筛法通过质数的倍数标记合数,而欧拉筛法优化了这一过程,确保每个合数只被其最小素因子筛一次,从而提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

质数定义

只有两个正因数(1和它本身)的自然数即为质数。比1大但不是质数的数称为合数

三种解法

基本方法

基本的方法是通过一个将需要判断的数字num从2–>num-1开始被除,可以整除则不符合其定义。
其所需判断的范围因为因子对称分布,可以缩小到2–>根号num。

public class 素数_基本方法 {
	public static void main(String[] args) {
		final int N = 100;
		for(int i=2;i<=N;i++) {
			boolean flag = true;
			for(int j=2;j*j<=i;j++) {
			if(i%j == 0) {
				flag = false;
				break;
				}
			}
			if(flag == true)System.out.println(i);
		}
	}
}

上述解法,需要对每一个数字进行判断。如果我们能够想到在1-100的数字中,除了2以外的倍数一定是合数的想法的话,那么可以考虑埃式筛法。
通过质数的倍数将合数筛掉,不需要再去判断合数。

埃式筛法

用1到sqrt(n)的素数将其倍数标记为合数即可。

public class 素数_埃式筛法 {
	public static void main(String[] args) {
		// 核心思路是
		// 用1到sqrt(n)的素数将其倍数标记为合数即可。
		final int NUM = 100;
		boolean isprime[] = new boolean[NUM+1];
		Arrays.fill(isprime,true);     // 假定所有的数为素数
		isprime[0] = false;
		isprime[1] = false;
		
		for(int i =2;i*i<=NUM;i++) {
			if(isprime[i] == true ) {
				for(int j=2;i*j<=NUM;j++) {
					isprime[i*j] = false;
				}
			}
		}

		for(int i =2;i<=NUM;i++) {
			if(isprime[i] == true)System.out.println(i);
		}
	}
}

上述解法,我们通过图分析的话,很容易能够直观的看到判断次数的减少。但是存在一个数字被多个质因子判断的情况,效率低下。如30 会被2、3、5各判断一次。
那么有没有只需要判断一次的解法呢?
于是,最优解法是欧拉筛法
读者自行梳理

欧拉筛法

public class 素数_欧拉筛法 {

	public static void main(String[] args) {
		// 其核心思路是
		// 每一个合数只被其最小素因子筛一次
		// 凡是合数,都有素因子
		final int NUM = 100;
		int[] prime = new int[NUM]; // 找到的具体的素数
		boolean[] isprime = new boolean[NUM+1];
		int count = 0;
		for(int i = 2;i<=NUM;i++) {
			if(isprime[i] == false) prime[count++] = i;   // 把当前素数i存放在prime数组第count位置,然后count++;
			
			for(int j = 0;j<count && i*prime[j]<=NUM;j++) {
				isprime[i * prime[j]] = true;   // prime[j]素数的i倍一定是合数
				if(i % prime[j] == 0) break;
				// i = prime[j] * k;   
				// i * prime[j+1]  = prime[j] * k * prime[j+1];
			}
		}	
		for(int i=0;i<count;i++) {
			System.out.println(prime[i]);
		}
	}
}

欧拉筛法的巧妙之处在每个合数只被其最小的质因子筛一次。以12为例,在for循环中,首先逻辑标识在数字6时被标记为true,不走if语句。往下内层for循环,j为0,对应数组质数为2,将24筛掉。j++时候,我们发现3*12=36,他存在一个2 * 18,只要18的时候将其筛掉即可。在if语句的break判断,注释中写到的内容反映其存在更小 的质因子。

结语:

在后面两种算法,有一句数学结论会更好理解。

所有的合数,都存在质因子。

​整体上,欧拉筛法是目前最常用的解法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值