Java-数素数 (20)

本文介绍了一个Java程序,该程序能够根据用户输入的两个正整数M和N(M≤N≤10000),输出从第M个素数到第N个素数之间的所有素数。程序使用了素数判断方法,并采用StringBuffer来格式化输出结果。

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

题目描述

令Pi表示第i个素数。现任给两个正整数M <= N <= 10000,请输出PM到PN的所有素数。

输入描述:

输入在一行中给出M和N,其间以空格分隔。

输出描述:

输出从PM到PN的所有素数,每10个数字占1行,其间以空格分隔,但行末不得有多余空格。

输入例子:

5 27

输出例子:

11 13 17 19 23 29 31 37 41 43

47 53 59 61 67 71 73 79 83 89

97 101 103
import java.util.Scanner;

public class countPrime {
	
	public static void main(String[] args) {

		Scanner in = new Scanner(System.in);
		int M = in.nextInt();
		int N = in.nextInt();
		long[] primeNums = new long[N];	//创建数组,用于存储第1-N位的素数
		int count = 0;					//存储当前查找的素数的数量
		int i = 2;
		//从2开始遍历,直到找出N个素数
		while(count < N) {
			if (isPrime(i)) {
				//System.out.println(i+":"+isPrime(i));
				primeNums[count] = i;
				count++;
				i++;
			}
			else {
				i++;
			}
		}
		StringBuffer sbBuffer = new StringBuffer();
		//从第M个素数开始输出,每一行输出10个
		for (int j = M-1; j < N; j++) {
			if (j % 10 != ((M-2)%10)) {
				sbBuffer.append(primeNums[j]).append(" ");
			}
			else {
				sbBuffer.append(primeNums[j]).append("\n");
			}
		}
		//删除StringBuffer结尾附加的空格或者换行符
		sbBuffer.deleteCharAt(sbBuffer.length()-1);
		System.out.println(sbBuffer);
	}
	//判断整数n是不是素数
	public static boolean isPrime(long n){
		for (int k = 2; k <= Math.sqrt(n); k++) {
			if (n % k == 0) {
				return false;
			}
		}
		return true;
		
	}

}


### 如何用Java编写判断素数的程序 在Java中,可以通过多种方式实现素数判断的功能。下面提供一种常见的方法来检测给定整数是否为素数。 #### 方法一:简单循环检查法 这种方法通过遍历从`2`至目标值平方根之间的所有整数,逐一尝试作为除去除目标值,以此判定该是否能被任何小于自身的整除。如果存在可以整除的情况,则说明此不是素数;反之则是素数[^4]。 ```java public class PrimeChecker { public static boolean isPrime(int num) { if (num <= 1) return false; for (int i = 2; i * i <= num; ++i) { // 只需测试到sqrt(num),因为因子总是成对出现 if (num % i == 0) return false; } return true; } public static void main(String[] args) { int testNumber = 17; System.out.println(testNumber + " 是素数吗?" + isPrime(testNumber)); } } ``` 上述代码定义了一个名为 `isPrime()` 的静态函,接受一个整型参返回布尔类型的真伪值表示输入字是否为素数。主函部分调用了这个辅助函来进行具体某个数(此处设定了变量 `testNumber` 来存储待测据)的素性检验,打印出结果。 为了提高效率,在实际应用中通常只需要考虑直到√n范围内的可能因子即可完成有效的筛选过程[^5]。 #### 方法二:埃拉托斯特尼筛法优化版 对于更大规模的据集或者频繁查询场景下,还可以采用更高效的算法——埃氏筛法及其改进版本。这里给出一段基于位运算的空间节省型实现: ```java import java.util.Arrays; public class SieveOfEratosthenes { private final byte[] sieve; /** * 构造器初始化指定大小的最大边界内所有的素数状态表. */ public SieveOfEratosthenes(int maxLimit) { this.sieve = new byte[(maxLimit >> 3) + 1]; Arrays.fill(this.sieve, (byte) 0xFF); // 初始化全置为1(即假设全部都是素数) setBit(0); setBit(1); for (long n = 2L; n * n < maxLimit;) { long m = nextClearBit(n); while ((m *= m) < maxLimit && !getBit(m)) { setBit((int)m); m += n; } n++; } } /** * 设置特定位置上的标志位为已占用/非素数. * * @param index 要设置的位置索引 */ private void setBit(long index) { if (index >= 0) { int byteIndex = (int)(index >>> 3); int bitMask = ~(1 << (index & 7)); sieve[byteIndex] &= bitMask; } } /** * 获取下一个未被标记过的最小合对应的起始点. * * @param start 开始寻找的地方 * @return 下一个可用作新轮次起点的合值 */ private long nextClearBit(long start) { do { int bytePos = (int)(start >>> 3); if (((sieve[bytePos]) | ~(-1)) != 0) { int bitOffset = Integer.numberOfTrailingZeros(~sieve[bytePos]); return ((bytePos << 3) | bitOffset); } else { start |= 7L; start++; } } while (++start > 0); throw new AssertionError(); } /** * 判断某一位是否已经被标记过. * * @param pos 需要检查的状态位编号 * @return 如果对应位已被清除则返回false,否则返回true */ private boolean getBit(int pos) { return (pos >= 0) && ((this.sieve[pos >>> 3] & (1 << (pos & 7))) != 0); } /** * 测试接口供外部调用以确认单个整数是不是素数. * * @param value 待查证的目标整数 * @return 若value确实属于素数范畴就回传True,反之False */ public boolean contains(int value) { return getBit(value); } public static void main(String[] args) { SieveOfEratosthenes soe = new SieveOfEratosthenes(1000000); System.out.printf("%d 是否是素数:%b%n", 9973, soe.contains(9973)); } } ``` 这段更为复杂的例子展示了如何利用预先计算好的大范围内所有素数的信息快速响应任意询问。虽然初次构建成本较高,但对于多次重复访问同一区间的情形特别有用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值