我正在尝试编写使用Eratosthenes筛子算出质数的代码。我必须包含一个函数,该函数将接受一个数字并乘以该数字的所有倍数。为了进行测试,我将第一个数字设置为2,将第二个数字设置为3。它适用于第一个数字,但不适用于第二个数字(无论数字的顺序如何,即我是否首先将3放入函数中)。我知道那里还有其他的Eratosthenes筛网,但我想尝试用我最初想到的方式来做。
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.println("Which number would you like to calculate up to?");
int n = input.nextInt();
input.close();
int x = 0;
int newNumber = 2;
int numbers[] = new int[n];
while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
int currentNumber = 2;
int finalNumber[] = markOfMultiples(n, numbers, currentNumber);
for(int y = 0;y < n-1;y++){
System.out.print(finalNumber[y] + ", ");
}
currentNumber = 3;
int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
for(int y = 0;y < n-1;y++){
System.out.println(secondNumber[y]);
}
}
public static int[] markOfMultiples(int n, int numbers[], int currentNumber){
int originalNumber = currentNumber;
while(currentNumber<n){
currentNumber = currentNumber + originalNumber;
int count2 = 0;
while(currentNumber != numbers[count2] && currentNumber<=n && count2<n){
count2++;
}
numbers[count2] = 0;
}
return numbers;
}
我得到的错误是:线程“主”中的异常java.lang.ArrayIndexOutOfBoundsException:20
在sieveOfEratosthenes.sieveOfEratosthenes.markOfMultiples(sieveOfEratosthenes.java:46)
在sieveOfEratosthenes.sieveOfEratosthenes.main(sieveOfEratosthenes.java:28)
第28行是我想起函数的时间:
int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
第46行是
while(currentNumber != numbers[count2] && currentNumber<=n && count2<20){
任何帮助将非常感激。如何继续调用该函数?
ps。请原谅变量名,因为在程序运行时我将对其进行更改。
最佳答案
如果您想使这种方法起作用,可以执行@Thierry建议的修复,以在while循环中先检查count2 < n
,然后再将其包围
numbers[count2] = 0
使用if子句检查count2是否不超出索引的末尾。例如
if (count2 < n) {
numbers[count2] = 0;
}
最后的挑战是当n变大时,如何多次调用
markOfMultiples()
函数。这不是您的基本方法的问题-您可以做到这一点,并且您的方法可以很好地工作,并且对于低位数字(例如10000个)具有可接受的性能。然而
我意识到这是一项任务,您想按自己的方式去做,但是您可能需要考虑该方法的一些功能-也许在使它起作用之后。
可读性-看着(标记)您的代码的人很容易理解它在做什么,并验证它是否对所有n值都能正确地工作?
尽量不要重复自己-例如考虑填充
numbers
数组的位置:while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
x
与newNumber
会有所不同吗?您是否需要两个变量?这种排序或重复发生在代码的其他位置-遵循的原理称为DRY (Don't Repeat Yourself)有没有更简单的方法可以将索引移至
originalNumber
方法中的markOfMultiples()
位置? (提示:是的,有)您是否真的需要numbers []数组中的实际数字?如果您想出如何为n的高值重复调用markOfMultiples,那么最终将得到很多零,并且质数会保留为整数值。如果使用数组索引为您提供质数,那么一个1和0(或
true
s和false
s)数组是否足够?