【Java 算法】埃氏筛法

该程序使用Java实现了埃拉托斯特尼筛法,通过标记素数的倍数来找出指定范围内的所有素数。它首先假设所有数字为素数,然后从2开始,将每个素数的倍数标记为合数。在过程中,程序计算了执行次数和标记次数,最后输出了找到的素数数量以及运行时间。
摘要由CSDN通过智能技术生成

 

 

import java.util.Scanner;

/*
 *  1 ~ sqrt(n) 之类的所有素数倍数去筛选,把素数的倍数标记为合数,剩下的都为素数
 *  埃氏算法:将素数的倍数标记为合数,剩下的都为素数
 */
public class 埃氏筛法 {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt(); // 给定一个值的范围,求 1 ~ n 之间的素数: 1 ~ Integer.MAX_VALUE -2 (2147483646 - 2)
		scan.close();
		long startTime = System.currentTimeMillis();
		// 假定所有 false 为素数,因为数组下表 0 开始,最高为索引为 n - 1 的数,所以 length + 1,就能得到最高位的 n 下标索引
		boolean isPrime[] = new boolean[n + 1]; // 利用索引下标特性作为正整数
		// 标记为 true 则是合数,标记为 false 为素数
		// 1 和 0 是合数
		isPrime[0] = true;
		isPrime[1] = true;
        //仅为测试数据量时间计数
		int countX = 0;
		long countY = 0;
		int countPrime = 0;
		// 假定 i ~ n 为素数,标记他们的倍数为合数即可,剩下没有标记到的都是素数
		/*
		 *  假如给定一个数 n = 36 , <算出它的倍数> 关系如下
		 *  a == 1,  2, 3,4,6  
		 *  b == 36,18,12,9,6
		 *  关系:n = a * b; ———> a = n / b; ———> b = n / a;
		 *  倍数排序:1,2,3,4,6, 6, 9, 12, 18,36
		 *  执行次数:1,2,3,4,6,n/6,n/4,n/3,n/2,n/1
		 *  从关系得知,执行次数 == sqrt(n)根号次,n = sqrt(n)2 的平方
		 *  编程中 index 可以:1*1=1,2*2=4,3*3=9,4*4=16,5*5=25,index * index < n == 36
		 *  执行次数 5 次
		 *  当我标记 2,3,4,5... ~ n 全部数的倍数时,剩下未标记的都是素数
		 */
		for (int i = 2; i * i < isPrime.length; i++) { // 9 * 9 = 81; 10 * 10 = 100;
			if (isPrime[i]) continue; // true 跳过已标记, 编程特性加大性能效率,跳过
			countX++;
			// j 从 2 开始标记倍数,倍数结果 <= n 范围
			for (int j = 2; i * j < isPrime.length; j++) { //倍数小于长度
				if (! isPrime[i]) { // 只要是倍数标记为合数,这个判断可以省略
					isPrime[i * j] = true;
					countY++;
				}
			}
		}
        //记录质数个数,只要为 false 都是质数
		for (boolean value : isPrime) if (! value) countPrime++;
        //打印执行时间与质数个数
		System.out.println("执行次数 = " + countX + " + " + countY);
		System.out.println("countPrime = " + countPrime);
		double useTimems = System.currentTimeMillis() - startTime;
		System.out.println("Ending time == " + useTimems / 1000 + "s");
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚妄狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值