我正在尝试编写能够使用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;
}
我得到的错误是:线程“main”中的异常java.lang.ArrayIndexOutOfBoundsException:20
at sieveOfEratosthenes.sieveOfEratosthenes.markOfMultiples(sieveOfEratosthenes.java:46)
at sieveOfEratosthenes.sieveOfEratosthenes.main(sieveOfEratosthenes.java:28)
第28行是我回忆起函数:int secondNumber[] = markOfMultiples(n, numbers, currentNumber);
第46行是while(currentNumber != numbers[count2] && currentNumber<=n && count2<20){
非常感谢任何帮助。我如何继续调用该函数?
P.S。请原谅变量名称,因为我将在程序运行时更改它们。
答案 0 :(得分:3)
如果你想让这种方法有效,你可以做@Thierry建议的修复,先在你的while循环中检查count2 < n
然后再包围这行
numbers[count2] = 0
使用if子句检查count2的不会超出索引的末尾。 e.g。
if (count2 < n) {
numbers[count2] = 0;
}
您最后的挑战是当n变得更大时,如何足够多次调用markOfMultiples()
函数。这不是你的基本方法的问题 - 你绝对可以做到这一点,你的方法将运作良好,并且对于低数字(例如高达10000)具有可接受的性能。
我意识到这是一项任务,你想按照自己的方式去做,但是你可能想要考虑一些你的方法的功能 - 也许在你完成它之后。
尽量不要重复自己 - 例如考虑填充numbers
数组的位置:
while(newNumber <= n){
numbers[x] = newNumber;
x++;
newNumber++;
}
x
会newNumber
与originalNumber
不同吗?你需要两个变量吗?这种排序或重复发生在代码的其他地方 - 坚持的原则称为DRY (Don't Repeat Yourself)
是否有更简单的方法可以在markOfMultiples()
方法的true
位置移动索引? (提示:是的,有)
你真的需要数字[]数组中的实际数字吗?如果你弄清楚如何重复调用你的markOfMultiples以获得高n值,那么你最终会得到很多零并且素数会作为整数值。如果使用数组索引给出素数,那么1和0(或false
s和{{1}} s)的数组是否足够?
答案 1 :(得分:1)
你需要测试count2&lt; n在访问号码之前[count2]:
while(count2 < n && currentNumber != numbers[count2] && currentNumber<= n){
count2++;
}