再帰関数:カウントダウン
CoddyのDartジャーニー「論理とフロー」セクションの一部 — レッスン 48/65。
さあ、シンプルなカウントダウン関数を使って、再帰を実践してみましょう。この演習は、実際のコードの中でベースケースと再帰ステップがどのように連携して機能するかを理解するのに役立ちます。
カウントダウン関数は、ある数値から開始し、0になるまで各数値を表示します。再帰によってこれがどのように機能するかを説明します。もし数値が0より大きい場合は、その値を表示し、その後、より小さい数値で同じ関数を呼び出します。数値が0に達したら、停止します。
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()を使用して、最初の入力を整数に変換します- 2つのパラメータを受け取る
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関数を呼び出してください
// messagePrefixのNull安全(null safety)の処理を忘れないようにしてください
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
論理とフローのすべてのレッスン
1リスト操作の応用
リストのプロパティ: first と lastリストの状態: isEmpty と isNotEmptyリストの反転リストへの追加: insertリストの削除: removeWhereリスト内の検索: indexOfリストのソートリストのシャッフルまとめ - リストオーガナイザー