Java Eratostenes筛,只打印给定天花板上的最大素数?
各位!!我有一个java应用程序,可以显示从2到给定数字(用户输入)的所有素数。如何从给定范围打印出最后一个数字,我的意思是最大的一个? 例如:如果用户输入是12,编译器只打印11,而不是2,3,5,7,11。 代码如下:Java Eratostenes筛,只打印给定天花板上的最大素数?,java,arrays,loops,sieve,Java,Arrays,Loops,Sieve,各位!!我有一个java应用程序,可以显示从2到给定数字(用户输入)的所有素数。如何从给定范围打印出最后一个数字,我的意思是最大的一个? 例如:如果用户输入是12,编译器只打印11,而不是2,3,5,7,11。 代码如下: package sieve_eratos; import java.util.Scanner; public class Sieve_Eratos { public static void main(String[] args) { // ge
package sieve_eratos;
import java.util.Scanner;
public class Sieve_Eratos {
public static void main(String[] args) {
// get the ceiling on our prime numbers
int N;
Scanner sc = new Scanner(System.in);
System.out.print("enter the prime number ceiling: ");
N = sc.nextInt();
sc.close();
int k = 0;
// init numbers array, where true denotes primality
boolean[] isPrime = new boolean[N];
// init possible primes
isPrime[0] = false; // 1 is not prime
for (int i = 1; i < N; i++) {
isPrime[i] = true;
k = k + 1;
}
// check every number >= 2 for primality
for (int i = 2; i <= N; i++) {
// i is prime if it hasn't been "crossed off" yet
if (isPrime[i - 1]) {
// print out the prime number
System.out.println(i);
// "cross off" all the subsequent multiples of i
//for (int j = 2*i; j <= N; j += i) {
for (int j = i * i; j <= N; j += i) { // more efficient
isPrime[j - 1] = false;
}
}
}
}
}
包装筛;
导入java.util.Scanner;
公共类筛网{
公共静态void main(字符串[]args){
//得到我们素数的上限
int N;
扫描仪sc=新的扫描仪(System.in);
System.out.print(“输入素数上限:”);
N=sc.nextInt();
sc.close();
int k=0;
//init numbers数组,其中true表示素性
布尔值[]isPrime=新布尔值[N];
//初始可能素数
isPrime[0]=false;//1不是素数
对于(int i=1;i=2的素数
对于(inti=2;i使用
Integer primeValues[]={2,3,5,7,11};//Here store all primes
NavigableSet<Integer> primeCollec=new TreeSet<>();
primeCollec.addAll(Arrays.asList(primeValues));
//Add all range prime into NavigableSet
int input=12;// Get the user input here
int output=primeCollec.lower(input);// Here is the desired output based on input
System.out.println(output);
Integer primeValues[]={2,3,5,7,11};//此处存储所有素数
NavigableSet primeCollec=新树集();
addAll(Arrays.asList(primeValues));
//将所有范围素数添加到NavigableSet
int input=12;//在此处获取用户输入
int output=primeCollec.lower(input);//这是基于输入的所需输出
系统输出打印项次(输出);
由于数字是连续数字(从1到N),我们可以从最大索引中检查素数标志(在您的代码中,它是布尔[]isPrime)
如果这是真的,那么它的索引和1(索引+1)之和将是我们想要的上限素数
代码如下:
public static int populateCeilingPrime(boolean[] flags)
{
int len = flags.length;
for(int i= len -1;i>=0;i--)
{
if(flags[i])
{
return i+1;
}
}
return 0;
}
所以您只需要调用上面的方法来填充天花板素数,在main方法的末尾使用以下代码
System.out.printf("The ceiling prime is %d ", populateCeilingPrime(isPrime));
不打印素数,您可以检查您要打印的数字是否大于您要打印的某个较早的数字,然后如果它是素数,并且更大,则将该素数保存为迄今为止最大的素数。一旦完成筛选过程,保存的素数应该是您想要的
像这样:
int maxPrime = 0;
for (int i = 2; i <= N; i++) {
// i is prime if it hasn't been "crossed off" yet
if (isPrime[i - 1]) {
if(i > maxPrime) {
maxPrime = i;
}
// "cross off" all the subsequent multiples of i
//for (int j = 2*i; j <= N; j += i) {
for (int j = i * i; j <= N; j += i) { // more efficient
isPrime[j - 1] = false;
}
}
}
System.out.println(maxPrime);
intmaxprime=0;
对于(int i=2;i您可能希望使用列表而不是数组。为什么不在for循环的上面和后面执行程序,只需在另一个for/while循环中从后向前检查您的数组。打印数字并在找到第一个素数后停止。@MarkusKoivisto的效率关键在于使用数组,而不是列表,以进行随机访问。计数和j必须标记倍数,而不是实际删除数字,以保持直接寻址(并标记)其他倍数的能力。是的,在这种情况下,最好只存储最后找到的素数的索引。这太多工作了。为什么不在完全筛选后从顶部搜索筛选后的数组。这是O(logn)步,而不是O(N/logn)。我看不出这有多大的工作量。与其再做一次搜索,他会在筛选完成后得到最大值。但我不会争辩,我没有从复杂性的角度分析我的方法。你在做O(N/logn)操作(为每个找到的素数更新maxPrime
变量)以节省O(logn)操作(即从数组顶部倒计时到第一个未标记的条目)。就复杂性而言,相邻素数之间的平均间距为O(logn)。我很高兴。:)我应该在我的第一条评论中更清楚。它应该是“为什么不在完全筛选后从顶部搜索筛选后的数组。这就是O(logn)步骤而不是O(N/log N)步骤”。