Java: Цикл For
С помощью цикла while решают любую задачу перебора, но его отличает многословность. Для while приходится отдельно заводить счетчик, отдельно задавать условие остановки и отдельно менять счетчик в теле цикла. Когда циклов немного, это терпимо. В реальном коде циклы встречаются на каждом шагу, и управлять тремя частями вручную утомительно, особенно когда количество повторов известно заранее.
Для таких случаев в Java есть цикл for. Он собирает все три части в одну строку. Посмотрим реализацию переворота строки через for:
public static String reverseString(String str) {
var result = "";
for (var i = 0; i < str.length(); i++) {
result = str.charAt(i) + result;
}
return result;
}
App.reverseString("code"); // "edoc"Запись i++ увеличивает счетчик на единицу. Это короткая форма для i = i + 1, и в заголовке цикла она встречается чаще всего. Сам код можно описать словами так:
Цикл с индексом
iначинается со значения0, повторяется, покаi < str.length(), и после каждого шага увеличиваетiна единицу
В заголовке цикла for ровно три части, разделенные точками с запятой:
- Начальное значение счетчика. Этот код выполняется один раз перед первой итерацией
- Предикат — условие повторения. Проверяется перед каждой итерацией, точно так же как в
while - Изменение счетчика. Этот код выполняется в конце каждой итерации
В остальном принцип работы такой же, как у while.
Разбор по шагам
Разберем, как отрабатывает цикл при вызове reverseString("go!"). До цикла result равен пустой строке:
reverseString("go!")
до цикла: result = ""
i=0: charAt(0) = 'g'
result = 'g' + "" = "g"
i=1: charAt(1) = 'o'
result = 'o' + "g" = "og"
i=2: charAt(2) = '!'
result = '!' + "og" = "!og"Каждый символ берется по индексу слева направо и приклеивается к началу результата. Поэтому строка собирается в обратном порядке.
Сравнение с while
Один и тот же перебор строки на двух циклах выглядит так:
for (var i = 0; i < str.length(); i++) { var i = 0;
System.out.println(str.charAt(i)); while (i < str.length()) {
} System.out.println(str.charAt(i));
i = i + 1;
│ │ }
└── счетчик задан в одной строке └── счетчик размазан по телуЦикл for держит все управление счетчиком в заголовке, поэтому тело остается чистым. Когда количество повторов понятно заранее, for читается лучше. Когда заранее неясно, сколько будет итераций, например при поиске простого числа, удобнее while.
Покажем еще пример с числовым счетчиком. Сложим числа от 0 до 9:
var sum = 0;
for (var i = 0; i < 10; i++) {
sum = sum + i;
}
System.out.println(sum); // => 45Счетчик начинается с нуля, цикл идет, пока i < 10, и на каждом шаге i растет на единицу. Внутри тела остается только накопление суммы.
Задание
Сэмвелл обнаружил, что его сообщения перехватываются в замке «Близнецы» и там читаются. Из-за этого их атаки перестали быть внезапными. Немного подумав, он разработал программу, которая бы шифровала сообщения по следующему алгоритму. Она бы брала текст и переставляла в нем каждые два подряд идущих символа.
App.encrypt("move"); // "omev"
App.encrypt("attack"); // "taatkc"
// Если число символов нечётное
// то последний символ остается на своем месте
App.encrypt("go!"); // "og!"Реализуйте статический метод App.encrypt(), который принимает на вход исходное сообщение и возвращает зашифрованное.
Java: Цикл For
С помощью цикла while решают любую задачу перебора, но его отличает многословность. Для while приходится отдельно заводить счетчик, отдельно задавать условие остановки и отдельно менять счетчик в теле цикла. Когда циклов немного, это терпимо. В реальном коде циклы встречаются на каждом шагу, и управлять тремя частями вручную утомительно, особенно когда количество повторов известно заранее.
Для таких случаев в Java есть цикл for. Он собирает все три части в одну строку. Посмотрим реализацию переворота строки через for:
public static String reverseString(String str) {
var result = "";
for (var i = 0; i < str.length(); i++) {
result = str.charAt(i) + result;
}
return result;
}
App.reverseString("code"); // "edoc"Запись i++ увеличивает счетчик на единицу. Это короткая форма для i = i + 1, и в заголовке цикла она встречается чаще всего. Сам код можно описать словами так:
Цикл с индексом
iначинается со значения0, повторяется, покаi < str.length(), и после каждого шага увеличиваетiна единицу
В заголовке цикла for ровно три части, разделенные точками с запятой:
- Начальное значение счетчика. Этот код выполняется один раз перед первой итерацией
- Предикат — условие повторения. Проверяется перед каждой итерацией, точно так же как в
while - Изменение счетчика. Этот код выполняется в конце каждой итерации
В остальном принцип работы такой же, как у while.
Разбор по шагам
Разберем, как отрабатывает цикл при вызове reverseString("go!"). До цикла result равен пустой строке:
reverseString("go!")
до цикла: result = ""
i=0: charAt(0) = 'g'
result = 'g' + "" = "g"
i=1: charAt(1) = 'o'
result = 'o' + "g" = "og"
i=2: charAt(2) = '!'
result = '!' + "og" = "!og"Каждый символ берется по индексу слева направо и приклеивается к началу результата. Поэтому строка собирается в обратном порядке.
Сравнение с while
Один и тот же перебор строки на двух циклах выглядит так:
for (var i = 0; i < str.length(); i++) { var i = 0;
System.out.println(str.charAt(i)); while (i < str.length()) {
} System.out.println(str.charAt(i));
i = i + 1;
│ │ }
└── счетчик задан в одной строке └── счетчик размазан по телуЦикл for держит все управление счетчиком в заголовке, поэтому тело остается чистым. Когда количество повторов понятно заранее, for читается лучше. Когда заранее неясно, сколько будет итераций, например при поиске простого числа, удобнее while.
Покажем еще пример с числовым счетчиком. Сложим числа от 0 до 9:
var sum = 0;
for (var i = 0; i < 10; i++) {
sum = sum + i;
}
System.out.println(sum); // => 45Счетчик начинается с нуля, цикл идет, пока i < 10, и на каждом шаге i растет на единицу. Внутри тела остается только накопление суммы.
Задание
Сэмвелл обнаружил, что его сообщения перехватываются в замке «Близнецы» и там читаются. Из-за этого их атаки перестали быть внезапными. Немного подумав, он разработал программу, которая бы шифровала сообщения по следующему алгоритму. Она бы брала текст и переставляла в нем каждые два подряд идущих символа.
App.encrypt("move"); // "omev"
App.encrypt("attack"); // "taatkc"
// Если число символов нечётное
// то последний символ остается на своем месте
App.encrypt("go!"); // "og!"Реализуйте статический метод App.encrypt(), который принимает на вход исходное сообщение и возвращает зашифрованное.
Ваше упражнение проверяется по этим тестам
import static org.assertj.core.api.Assertions.assertThat;
class AppTest {
public static void main(String[] args) {
assertThat(App.encrypt("attack")).isEqualTo("taatkc");
assertThat(App.encrypt("go!")).isEqualTo("og!");
}
}Решение учителя откроется через:
20:00
