Java: Возврат из циклов
Работа с циклами обычно сводится к двум сценариям. В первом результат накапливается во время итераций, а работа с ним идет уже после цикла. Такой подход называют агрегацией, и переворот строки относится к нему. Во втором цикл выполняется до достижения нужного результата и завершается досрочно. Так устроена, например, проверка простого числа, которое делится без остатка только на себя и на единицу.
Рассмотрим алгоритм проверки простоты числа. Будем делить искомое число x на все числа из диапазона от двух до x - 1 и смотреть остаток. Если в этом диапазоне не нашелся делитель, который делит x без остатка, значит, перед нами простое число.
Проверка простоты числа 5: пошаговый разбор
- Берем число
x = 5. Возможные делители ищем в диапазоне от 2 доx - 1, то есть от 2 до 4 - Делим 5 на 2. Остаток равен 1, делителя не нашли, продолжаем
- Делим 5 на 3. Остаток равен 2, делителя не нашли, продолжаем
- Делим 5 на 4. Остаток равен 1, делителя не нашли, завершаем перебор
Итог: в диапазоне от 2 до 4 не нашлось ни одного числа, на которое 5 делится без остатка. Значит, 5 — простое число.
Поиск делителей достаточно ограничить половиной числа. Например, 11 не делится на 2, 3, 4, 5, а на числа больше своей половины оно тем более не разделится. Значит, алгоритм можно оптимизировать и проверять деление только до x / 2:
public static boolean isPrime(int number) {
if (number < 2) {
return false;
}
var divider = 2;
while (divider <= number / 2) {
if (number % divider == 0) {
return false;
}
divider++;
}
return true;
}
App.isPrime(1); // false
App.isPrime(2); // true
App.isPrime(3); // true
App.isPrime(4); // falseЕсли быть честными до конца, для решения задачи хватит проверки чисел до квадратного корня из number. Но здесь важно сосредоточиться на работе с условием внутри цикла
Главный прием этого урока — выход из метода прямо изнутри цикла:
while (...) {
if (условие) {
return значение; ← выход из метода (и из цикла)
}
...
}
─────────────────────────────────
Без return цикл доходит до концаАлгоритм построен так, что при последовательном делении на числа до x / 2 достаточно найти хотя бы один делитель без остатка. Тогда переданный аргумент — составное число, и дальнейшие вычисления не имеют смысла. В этом месте стоит возврат false, и return сразу завершает и цикл, и весь метод.
И только если цикл отработал целиком и ни один делитель без остатка не нашелся, выполнение дойдет до последней строки. Метод вернет true, потому что число оказалось простым.
Задание
Реализуйте статический метод App.hasChar(), который проверяет (с учётом регистра), содержит ли строка указанную букву. Метод принимает два параметра:
- Строка
- Буква для поиска
App.hasChar("Renly", 'R'); // true
App.hasChar("Renly", 'r'); // false
App.hasChar("Tommy", 'm'); // true
App.hasChar("Tommy", 'd'); // falseПолезное
Java: Возврат из циклов
Работа с циклами обычно сводится к двум сценариям. В первом результат накапливается во время итераций, а работа с ним идет уже после цикла. Такой подход называют агрегацией, и переворот строки относится к нему. Во втором цикл выполняется до достижения нужного результата и завершается досрочно. Так устроена, например, проверка простого числа, которое делится без остатка только на себя и на единицу.
Рассмотрим алгоритм проверки простоты числа. Будем делить искомое число x на все числа из диапазона от двух до x - 1 и смотреть остаток. Если в этом диапазоне не нашелся делитель, который делит x без остатка, значит, перед нами простое число.
Проверка простоты числа 5: пошаговый разбор
- Берем число
x = 5. Возможные делители ищем в диапазоне от 2 доx - 1, то есть от 2 до 4 - Делим 5 на 2. Остаток равен 1, делителя не нашли, продолжаем
- Делим 5 на 3. Остаток равен 2, делителя не нашли, продолжаем
- Делим 5 на 4. Остаток равен 1, делителя не нашли, завершаем перебор
Итог: в диапазоне от 2 до 4 не нашлось ни одного числа, на которое 5 делится без остатка. Значит, 5 — простое число.
Поиск делителей достаточно ограничить половиной числа. Например, 11 не делится на 2, 3, 4, 5, а на числа больше своей половины оно тем более не разделится. Значит, алгоритм можно оптимизировать и проверять деление только до x / 2:
public static boolean isPrime(int number) {
if (number < 2) {
return false;
}
var divider = 2;
while (divider <= number / 2) {
if (number % divider == 0) {
return false;
}
divider++;
}
return true;
}
App.isPrime(1); // false
App.isPrime(2); // true
App.isPrime(3); // true
App.isPrime(4); // falseЕсли быть честными до конца, для решения задачи хватит проверки чисел до квадратного корня из number. Но здесь важно сосредоточиться на работе с условием внутри цикла
Главный прием этого урока — выход из метода прямо изнутри цикла:
while (...) {
if (условие) {
return значение; ← выход из метода (и из цикла)
}
...
}
─────────────────────────────────
Без return цикл доходит до концаАлгоритм построен так, что при последовательном делении на числа до x / 2 достаточно найти хотя бы один делитель без остатка. Тогда переданный аргумент — составное число, и дальнейшие вычисления не имеют смысла. В этом месте стоит возврат false, и return сразу завершает и цикл, и весь метод.
И только если цикл отработал целиком и ни один делитель без остатка не нашелся, выполнение дойдет до последней строки. Метод вернет true, потому что число оказалось простым.
Задание
Реализуйте статический метод App.hasChar(), который проверяет (с учётом регистра), содержит ли строка указанную букву. Метод принимает два параметра:
- Строка
- Буква для поиска
App.hasChar("Renly", 'R'); // true
App.hasChar("Renly", 'r'); // false
App.hasChar("Tommy", 'm'); // true
App.hasChar("Tommy", 'd'); // falseПолезное
Ваше упражнение проверяется по этим тестам
import static org.assertj.core.api.Assertions.assertThat;
class AppTest {
public static void main(String[] args) {
assertThat(App.hasChar("Renly", 'R')).isTrue();
assertThat(App.hasChar("Renly", 'r')).isFalse();
assertThat(App.hasChar("Tommy", 'm')).isTrue();
assertThat(App.hasChar("Tommy", 'd')).isFalse();
assertThat(App.hasChar("Tommy", 'y')).isTrue();
}
}Решение учителя откроется через:
20:00
