Ниже приведена одна из первых программ, которые я сделал (с помощью Интернета) на Java. Это программа, которая проверяет, является ли заданное целое число простым или нет, и запрашивает у пользователя обратную связь. Если пользовательский ввод не является целым числом, он выводит, что он не является целым числом. Последнее также происходит при вводе больших целых чисел. Это код:Почему этот первичный контролер работает, а не работает, если я попытаюсь сделать его более эффективным.
import java.util.Scanner;
class BasicPrime1 {
public static void main(String[] args) {
try {
System.out.println("Enter an Integer: ");
Scanner sc = new Scanner(System.in);
int i;
int number = Integer.parseInt(sc.nextLine());
// 1 and numbers smaller than 1 are not prime
for (i = 1; number <= i;) {
System.out.println("NOT a prime!");
break;
}
// Number is not prime if the remainder of a division (modulus) is 0
for (i = 2; i < number; i++) {
int n = number % i;
if (n == 0) {
System.out.println("NOT a prime!");
break;
}
}
// I do not understand why the if-statement below works.
if(i == number) {
System.out.println("YES! PRIME!");
}
}
catch(NumberFormatException nfe) {
System.out.println("Not an integer!");
}
}
}
Эта программа выполняет свою работу, но я не знаю, почему работает эта часть с if-statement. Как возможно, что «i == number» дает значение true (он печатает «YES! PRIME» при вводе простого числа)? Локальная переменная i увеличивается в for-loop, но оператор if находится вне цикла for.
/редактировать ниже параграф нонсенс, как Jim Lewis points out
Думая об этом сейчас, единственная причина, я могу думать о том, что это так, потому что проверки оператора ==, если я-`объектно 'и number-'object' относятся к одному и тому же «типу» (т. е. имеют ссылку на один и тот же объект). Поскольку они оба относятся к типу примитивных целых чисел, эта программа ловит целые числа (другой вход генерирует исключение NumberFormatException, которое выдается и выводит «Не целое число»). Те, которые являются штрихами, передают первый цикл for, а затем магическое if-statement дает «true», и он печатает «YES! PRIME!».
Я нахожусь на правильном пути?
Я улучшил эту программу, удалив волшебную если-заявление и изменить его для если-то еще-заявление, как это: (/редактирования исправлена проблема с кодом, благодаря answer of ajb)
boolean factorFound = false;
for (i = 2; i < Math.sqrt(number) + 1; i++) {
int n = number % i;
if (n == 0) {
factorFound = false;
break;
}
else {
factorFound = true;
}
}
if(factorFound == false) System.out.println("NOT a prime!");
if(factorFound == true) System.out.println("YES! PRIME!");
Подойдя только к квадратному корню из входного номера, время вычисления улучшается (я знаю, что его можно улучшить даже путем проверки нечетных чисел или использования AKS Primality Test, но это не относится к точке).
Мой главный вопрос: почему я не смог повысить эффективность первой программы (с магическим if-утверждением) таким же образом. Когда я улучшаю for-loop как это »(i = 2; i < Math.sqrt (число) + 1; i ++)" в первой программе он больше не распечатывает "YES! PRIME!" когда вы вводите штрих. Он дает пробел. Даже если мое предыдущее объяснение правильное, чего, вероятно, нет, - это не объясняется.
Вы можете просветить меня.
ANSWER: int i is outside of scope of for-loop and after going through the for-loop multiple times upto number the value of i will reach the value number, when we can be sure it is a prime. Кроме того, после проверки исчезнувшего «ДА! ПРЕМЬЕР!» в очередной раз оказывается, что на самом деле можно изменить число как в if-statement, так и for-loop на (Math.sqrt (number) + 1) и иметь рабочий код. Поэтому вопрос был основан на ложной предпосылке.
Во втором примере вы не позволяете ему проходить весь цикл. Если n равно 0, вы знаете, что это не простое, и вы можете выйти из цикла прямо сейчас, что правильно. Но если n не равно 0, вам нужно снова пройти цикл, но, как вы его закодировали, вы выходите. Вам нужно продолжать проходить цикл, а затем, когда цикл завершен, вы проверяете, уходите ли вы, потому что вы обнаружили, что это не просто, или весь цикл завершен. Лучший способ - определить логическое значение, например 'factorFound'; инициализируйте его значением false, установите его значение true перед разрывом и проверьте его после завершения цикла. – ajb
А вы правы. Если число% i отличное от нуля, это не означает, что нет другого более высокого i, для которого оно равно нулю, и, следовательно, второй пример может давать ложные срабатывания. Я обновил код с помощью boolean, и теперь он работает правильно. –