Рекурсивная функция: обратный отсчёт
Часть раздела Логика и управление потоком путешествия по Dart на Coddy — урок 48 из 65.
Пришло время применить рекурсию на практике с помощью простой функции обратного отсчета. Это упражнение поможет вам понять, как базовый случай и рекурсивный шаг работают вместе в реальном коде.
Функция обратного отсчета начинается с числа и выводит каждое число до нуля. Вот как рекурсия заставляет это работать: если число больше нуля, выведите его, а затем вызовите ту же функцию с меньшим числом. Когда число достигнет нуля, остановитесь.
void countdown(int number) {
if (number <= 0) {
print("Done!");
return; // Базовый случай — остановиться здесь
}
print(number);
countdown(number - 1); // Рекурсивный шаг
}Базовый случай проверяет условие number <= 0 — в этот момент мы прекращаем вызов функции. Рекурсивный шаг вызывает countdown(number - 1), что представляет собой ту же задачу, но с меньшим входным значением, постепенно приближая нас к базовому случаю.
Когда вы вызываете countdown(3), она выводит 3, затем вызывает countdown(2), которая выводит 2, затем вызывает countdown(1), которая выводит 1, затем вызывает countdown(0), которая выводит "Done!" и останавливается.
Задание
ЛегкоСоздайте программу, которая реализует рекурсивный таймер обратного отсчета с настраиваемыми сообщениями. Ваша программа продемонстрирует рекурсию, ведя обратный отсчет от заданного числа и отображая персонализированные сообщения на каждом этапе.
- Прочитайте строковый ввод, представляющий начальное число для обратного отсчета
- Прочитайте строковый ввод, представляющий префикс настраиваемого сообщения (например,
"Launch in","Timer"или"Countdown") - Преобразуйте первый ввод в целое число с помощью
int.parse() - Создайте рекурсивную функцию с именем
customCountdown, которая принимает два параметра: - Целое число
number, представляющее текущее значение обратного отсчета - Строку
messagePrefixдля настраиваемого сообщения - Функция должна реализовывать следующую логику:
- Базовый случай: Если число меньше или равно 0, выведите
"Countdown complete!"и завершите выполнение (return) - Рекурсивный шаг: Выведите префикс сообщения, за которым следует текущее число, затем вызовите саму себя с параметром
number - 1 - Вызовите функцию
customCountdownс преобразованным числом и префиксом сообщения - Отобразите результаты в точном формате, показанном ниже
Например, если входные данные — "5" и "Launch in", ваша программа должна вывести:
Starting countdown from: 5
Message prefix: Launch in
========================
Launch in 5
Launch in 4
Launch in 3
Launch in 2
Launch in 1
Countdown complete!Если входные данные — "3" и "Timer", ваша программа должна вывести:
Starting countdown from: 3
Message prefix: Timer
========================
Timer 3
Timer 2
Timer 1
Countdown complete!Если входные данные — "0" и "Ready", ваша программа должна вывести:
Starting countdown from: 0
Message prefix: Ready
========================
Countdown complete!Ваша программа должна реализовывать рекурсивную функцию customCountdown, которая вызывает саму себя с уменьшенным числом до тех пор, пока не будет достигнут базовый случай. Функция должна выводить настраиваемое сообщение с текущим числом при каждом рекурсивном вызове, демонстрируя, как рекурсия разбивает задачу на более мелкие, идентичные подзадачи. Используйте интерполяцию строк для форматирования сообщений обратного отсчета в виде "$messagePrefix $number".
Шпаргалка
Рекурсивная функция обратного отсчета демонстрирует, как работает рекурсия, ведя отсчет от числа до нуля:
void countdown(int number) {
if (number <= 0) {
print("Done!");
return; // Базовый случай — остановиться здесь
}
print(number);
countdown(number - 1); // Рекурсивный шаг
}Базовый случай проверяет, выполняется ли условие number <= 0, чтобы остановить рекурсию. Рекурсивный шаг вызывает ту же функцию с number - 1, приближаясь к базовому случаю.
При вызове countdown(3) она выводит 3 → 2 → 1 → "Done!", совершая последовательные рекурсивные вызовы с уменьшенными значениями.
Попробуйте сами
import 'dart:io';
// TODO: Создайте здесь вашу функцию customCountdown
// Не забудьте обработать базовый случай (число <= 0) и рекурсивный шаг
void main() {
// Чтение ввода
String? startingNumber = stdin.readLineSync();
String? messagePrefix = stdin.readLineSync();
// Преобразование строки в целое число
int number = int.parse(startingNumber!);
// Отображение начальной информации
print('Starting countdown from: $number');
print('Message prefix: $messagePrefix');
print('========================');
// TODO: Вызовите здесь вашу функцию customCountdown
// Не забудьте обработать безопасность null для messagePrefix
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутая работа со списками
Свойства списка: first и lastСостояние списка: isEmpty и isNotEmptyРазворот спискаДобавление в список: insertУдаление из списка: removeWhereПоиск в списке: indexOfСортировка спискаПеремешивание спискаИтоги — Органайзер списков4Продвинутая работа с Map
Итерация по MapПроверка ключей и значенийСвойства Map: keys и valuesУсловное добавление: putIfAbsentУдаление записей из MapВложенные MapИтоги — Обновление инвентаря7Продвинутые функции
Анонимные функцииПередача функций в качестве аргументовПонимание замыканийВведение в рекурсиюРекурсивная функция: обратный отсчётРекурсивная функция: факториалИтоги — Обработчик списков2Функциональные операции со списками
Преобразование с помощью 'map'Фильтрация с помощью 'where'Использование '.toList()'Проверка условий с помощью 'any'Условия с 'every'Поиск с помощью 'firstWhere'Повторение — фильтрация данных5Проект: Калькулятор корзины
Настройка проектаДобавление товаров в корзину3Множества
Что такое множество?Создание множестваДобавление и удаление элементовПроверка наличия элементов в множествеПреобразование списка в множествоОбъединение множествПересечение множествРазность множествИтоги: уникальный список гостей