再帰関数:階乗
CoddyのDartジャーニー「論理とフロー」セクションの一部 — レッスン 49/65。
階乗は、再帰を説明するのに最適な古典的な数学的演算です。正の整数 n の階乗(n! と表記)は、1 から n までのすべての正の整数の積です。例えば、5! = 5 × 4 × 3 × 2 × 1 = 120 となります。
階乗が再帰に最適である理由は、それが自然に、より小さく同一の問題へと分解されるからです。5! を計算するには、それを 5 × 4! と考えることができます。そして 4! は単に 4 × 3! であり、以下同様に続きます。このパターンは、1 に等しい 1! に到達するまで続きます。
int factorial(int n) {
if (n <= 1) {
return 1; // ベースケース
}
return n * factorial(n - 1); // 再帰ステップ
}基底ケースは、n <= 1のときに再帰を停止し、1を返します。再帰ステップでは、現在の数値に1つ小さい数値の階乗を掛けます。factorial(5)を呼び出すと、5 * factorial(4)を返し、それは5 * 4 * factorial(3)を返し、基底ケースに達するまでこれが繰り返されます。
このアプローチは、問題を同じ問題のより単純な形式に分解することで、再帰がいかにエレガントに問題を解決するかを示しており、複雑な計算を自然で直感的なものに感じさせます。
チャレンジ
簡単再帰を使用して複数の数値の階乗を計算するプログラムを作成してください。このプログラムでは、数値のリストを処理し、それぞれの階乗を計算することで、再帰的な階乗関数の仕組みを実証します。
- カンマで区切られた数値を含む文字列入力を読み取ります(例:
"3,5,0,7")。 - 入力文字列を個々の数値に分割し、それぞれを整数に変換します。
- 整数パラメータ
nを受け取るfactorialという名前の再帰関数を作成します。 factorial関数は以下のロジックを実装する必要があります:- ベースケース:
nが1以下の場合は、1を返します。 - 再帰ステップ:
nにfactorial(n - 1)を掛けた値を返します。 - 入力リストの各数値について、作成した再帰関数を使用して階乗を計算します。
- 各数値とそれに対応する階乗の結果を表示します。
- すべての階乗結果の合計を計算して表示します。
例えば、入力が "4,3,2" の場合、プログラムは以下のように出力する必要があります:
Factorial Calculator
====================
Processing numbers: [4, 3, 2]
====================
Factorial Results:
4! = 24
3! = 6
2! = 2
====================
Sum of all factorials: 32
Calculation completed successfully入力が "5,0,1" の場合、プログラムは以下のように出力する必要があります:
Factorial Calculator
====================
Processing numbers: [5, 0, 1]
====================
Factorial Results:
5! = 120
0! = 1
1! = 1
====================
Sum of all factorials: 122
Calculation completed successfully入力が "6" の場合、プログラムは以下のように出力する必要があります:
Factorial Calculator
====================
Processing numbers: [6]
====================
Factorial Results:
6! = 720
====================
Sum of all factorials: 720
Calculation completed successfullyプログラムは、ベースケースに達するまで値を減らしながら自身を呼び出す再帰的な factorial 関数を実装する必要があります。この関数は、再帰によって階乗計算がどのように小さく同一のサブ問題に分解されるかを示す必要があります。階乗の結果を "$n! = $result" の形式でフォーマットするには、文字列補間を使用してください。数学的な定義により 0! は 1 に等しく、ベースケースでこれを正しく処理する必要があることに注意してください。
チートシート
正の整数 n の階乗(n! と表記)は、1 から n までのすべての正の整数の積です。例えば、5! = 5 × 4 × 3 × 2 × 1 = 120 です。
階乗は、より小さく同一の問題に分解できるため、再帰に最適です。5! = 5 × 4!、4! = 4 × 3! と続き、1! = 1 に達するまで繰り返されます。
int factorial(int n) {
if (n <= 1) {
return 1; // ベースケース
}
return n * factorial(n - 1); // 再帰ステップ
}ベースケースは n <= 1 のときに再帰を停止し、1 を返します。再帰ステップでは、現在の数値に次の小さな数値の階乗を掛けます。
自分で試してみよう
import 'dart:io';
// TODO: ここに再帰的な階乗関数を作成してください
void main() {
// カンマ区切りの数値を含む入力文字列を読み込む
String? input = stdin.readLineSync();
// 入力を分割し、整数に変換する
List<int> numbers = input!.split(',').map((str) => int.parse(str.trim())).toList();
// TODO: 以下の処理を行うコードを記述してください:
// 1. 階乗関数を使用して各数値を処理する
// 2. すべての階乗の合計を計算する
// 3. 指定された形式で結果を表示する
print("Factorial Calculator");
print("====================");
print("Processing numbers: $numbers");
print("====================");
print("Factorial Results:");
// TODO: ここで階乗の結果を計算し、表示してください
print("====================");
// TODO: すべての階乗の合計を表示してください
print("Calculation completed successfully");
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
論理とフローのすべてのレッスン
1リスト操作の応用
リストのプロパティ: first と lastリストの状態: isEmpty と isNotEmptyリストの反転リストへの追加: insertリストの削除: removeWhereリスト内の検索: indexOfリストのソートリストのシャッフルまとめ - リストオーガナイザー