Во-первых, давайте упростим ввод вашего числа:
Scanner in = new Scanner(System.in);
int input = 0;
while (input <= 1) {
System.out.println("Give an int bigger than 1: ");
input = in.nextInt();
if (input <= 1) {
System.out.println("The int must be bigger than 1!.");
}
}
in.close();
Минимизируя использование пробела, ваш друг не был прав насчет:
//now first i wrote it without "+1" but my friend changed it to +1
boolean[] x = new boolean[input + 1];
x[0]=false;
Поскольку вы печатаете только простые числа меньшечем input
(даже если input
- простое число), и вы пропускаете 0 и 1, вы можете сделать x
на три элемента короче:
boolean x[] = new boolean[input - 2]; // all initialized to false
Любая петля for
всегда можетразмотаться на цикл while
:
for (int i = 2; i < x.length; i++) {
Из трех элементов, разделенных точкой с запятой в настройке цикла for
, первый идет перед циклом while
, второй - while
условие цикла, а третье - последний оператор в цикле while
:
int i = 2;
while (i < input) { // 'input' instead of 'x.length' in our new design
// (the rest of the code that follows below goes here)
i++;
}
Это потенциальная проблема:
while (x[i])
{
i++;
}
Поскольку проверка границ на * 1028 не выполняется* до следующего x[i]
.Это работало для вас ранее из-за дополнительного неиспользуемого пространства, выделенного в x
.Теперь нам нужно быть более точным:
while (x[i - 2]) {
if (++i >= input) {
break outer;
}
}
Мы используем i - 2
, поскольку пропускаем пропущенные записи 0 и 1.Мы используем break outer;
вместо просто break;
, поскольку нам нужно выйти из цикла while
, который включает этот цикл while
.Итак, вернитесь и измените:
while (i < input) {
выше вместо этого на:
outer: while (i < input) {
Преобразование этого цикла for
несколько отличается из-за нежелательного умножения:
for (int j = i; j*i < input; j++) {
x[i * j] = true;
}
Мы собираемся многократно добавлять i
вместо умножения на i
.Это немного менее эффективно в начале, но в остальном хорошо:
int j = i + i;
while (j < input) {
x[j - 2] = true;
j += i;
}
Этот тест не нужен:
if (! x[i] && i < input)
Как мы уже знаем, x[i]
- это false
и i < input
из нашей работы выше.Так что просто закончите с:
System.out.println("The number " + i + " is prime.");
i++; // we added this earlier to finish off our first 'for' to 'while' conversion
Если вы внимательно следите за этими изменениями, то теперь у вас должна быть рабочая программа, в которой нет циклов for
, нет умножения и нет потерянных элементов массива.