Работа с флагами в Rust
Сейчас мы научимся работать с флагами.
Флаг - это специальная переменная, которая
может принимать только два значения:
true и false. С помощью флагов
можно решать задачи, проверяющие отсутствие
чего-либо: к примеру, можно проверить, что
в строке нет определенной буквы.
Давайте решим следующую задачу: дана строка
"abcde", нужно проверить, есть ли в ней
буква 'c'. Если есть - выведем
"Y", если нет - выведем "N".
Для начала давайте попробуем вывести
"Y". Для этого переберем все символы
строки и ифом будем спрашивать, равен ли
текущий символ букве 'c'. Если равен -
выведем "Y":
fn main() {
let text = "abcde";
for ch in text.chars() {
if ch == 'c' {
println!("Y"); // выведет Y
}
}
}
Но наше решение не очень хорошо: ведь если
в строке будет не одна буква 'c',
а несколько, то "Y" выведется
несколько раз. Давайте запишем эту букву
дважды и убедимся в этом:
fn main() {
let text = "abccde";
for ch in text.chars() {
if ch == 'c' {
println!("Y"); // выведет несколько раз
}
}
}
Поправим проблему: завершим цикл с помощью
break, если буква уже найдена:
fn main() {
let text = "abccde";
for ch in text.chars() {
if ch == 'c' {
println!("Y"); // выведет Y
break;
}
}
}
Давайте теперь попробуем сделать так, чтобы,
если в строке вообще нет буквы 'c',
выводилось "N". Распространенным
заблуждением будет добавить else к нашему
ифу - в этом случае "N" будет выводиться
на все символы, не являющиеся буквой 'c':
fn main() {
let text = "abcde";
for ch in text.chars() {
if ch == 'c' {
println!("Y"); // выведет на букве c
} else {
println!("N"); // выведет на буквах a, b, d и e
}
}
}
Итак, идея добавить else - плохая
идея, не рабочая. Для решения задач подобного
типа (такие задачи встречаются достаточно
часто) и используют так называемые флаги.
Как уже упоминалось выше, флаг - это такая
переменная, которая может принимать два
значения: true или false.
Итак, давайте сделаем переменную flag
с таким значением: если она равна true,
то в строке есть буква 'c', а если
false, то такой буквы нет.
Изначально поставим переменную flag
в значение false - то есть будем считать,
что буквы 'c' в строке нет:
fn main() {
let text = "abcde";
let flag = false; // считаем, что буквы c в строке нет
}
Затем запустим цикл с ифом так, как мы делали
это раньше. Если цикл обнаружит, что в строке
есть буква 'c' - то поставим переменную
flag в значение true и выйдем
из цикла с помощью break:
fn main() {
let text = "abcde";
let mut flag = false; // считаем, что буквы c в строке нет
for ch in text.chars() {
if ch == 'c' {
flag = true; // буква есть - переопределим переменную flag
break;
}
}
}
Ответ на вопрос, есть ли в строке буква
'c' или нет, мы можем дать только после
цикла. И этот ответ у нас уже есть: после цикла
переменная flag могла остаться
false или могла сменить свое значение
на true, если цикл обнаружил в строке
букву 'c':
fn main() {
let text = "abcde";
let mut flag = false;
for ch in text.chars() {
if ch == 'c' {
flag = true;
break;
}
}
// тут переменная flag равна или true, или false
}
Теперь после цикла мы можем сделать иф, который
посмотрит на переменную flag и выведет
на экран "Y" или "N":
fn main() {
let text = "abcde";
let mut flag = false;
for ch in text.chars() {
if ch == 'c' {
flag = true;
break;
}
}
if flag == true {
println!("Y"); // выведет Y
} else {
println!("N");
}
}
Дана строка:
let text = "program";
Проверьте, есть ли в ней буква 'r'.
Если есть - выведите "Y", а если нет -
выведите "N".
Дана строка:
let text = "hello";
Проверьте, есть ли в ней буква 'x'.
Если есть - выведите "Y", а если нет -
выведите "N".