Menu
Coddy logo textTech

Рекурсивная функция: обратный отсчёт

Часть раздела Логика и управление потоком путешествия по 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!" и останавливается.

challenge icon

Задание

Легко

Создайте программу, которая реализует рекурсивный таймер обратного отсчета с настраиваемыми сообщениями. Ваша программа продемонстрирует рекурсию, ведя обратный отсчет от заданного числа и отображая персонализированные сообщения на каждом этапе.

  1. Прочитайте строковый ввод, представляющий начальное число для обратного отсчета
  2. Прочитайте строковый ввод, представляющий префикс настраиваемого сообщения (например, "Launch in", "Timer" или "Countdown")
  3. Преобразуйте первый ввод в целое число с помощью int.parse()
  4. Создайте рекурсивную функцию с именем customCountdown, которая принимает два параметра:
    • Целое число number, представляющее текущее значение обратного отсчета
    • Строку messagePrefix для настраиваемого сообщения
  5. Функция должна реализовывать следующую логику:
    • Базовый случай: Если число меньше или равно 0, выведите "Countdown complete!" и завершите выполнение (return)
    • Рекурсивный шаг: Выведите префикс сообщения, за которым следует текущее число, затем вызовите саму себя с параметром number - 1
  6. Вызовите функцию customCountdown с преобразованным числом и префиксом сообщения
  7. Отобразите результаты в точном формате, показанном ниже

Например, если входные данные — "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
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком