- HOME >
- Jamstack用語集 >
- Recursion(再帰関数)
Recursion(再帰関数)
リカーション
再帰関数を分かりやすく
再帰関数とは、自分自身を呼び出す関数のことを言います。この概念は初めて聞くと「一体どういうこと?」って思いますよね?でも、安心してください。少し具体的な例を挙げることで理解しやすくなります。
例えば、ある数から0までカウントダウンする関数を作りたいとします。この時、関数は自分自身を呼び出すことで、カウントダウンを行うことができます。自分自身を呼び出すときには、引数として渡された数値から1を引いた値を渡します。そして、0までカウントダウンしたら、もう自分自身を呼び出さないようにします。これが再帰関数の基本的な動作です。
では、この再帰関数を分かりやすい例え話で説明してみましょう。再帰関数は、ロシアの伝統的なおもちゃである「マトリョーシカ」に似ています。マトリョーシカは、中に小さなマトリョーシカが入っていて、それを開けるとさらに小さなマトリョーシカが…というように、中に何層もの同じ形のおもちゃが入っていますよね。
このマトリョーシカの各層を一つ一つ取り出していく行為を、関数が自分自身を呼び出す行為に見立ててみると、再帰関数のイメージが掴みやすいかもしれません。大きなマトリョーシカから始まり、その中の小さなマトリョーシカを取り出すたびに、自分自身(マトリョーシカを開ける行為)を呼び出す、というわけです。
再帰関数、難しいですよね〜。でも一度理解してしまえば、非常にパワフルなツールとなるので、頑張って理解してみてください。ここまで大丈夫ですか?
結論
再帰関数は、その定義の中で自分自身を呼び出す関数のことを指します。これは、一見すると奇妙に思えるかもしれませんが、再帰的なアプローチは複雑な問題を解決する上で非常に有効な手段となります。再帰関数は、問題をより管理しやすい小さな問題に分解するのに役立ちます。
再帰関数の一般的な構造は以下のようになります。
- 基本ケース(終了条件): 再帰を停止する条件。この条件が満たされると、関数は自分自身を再び呼び出すことなく値を返します。
- 再帰ケース: 基本ケースが満たされない場合、関数は自身を再度呼び出します。通常、この呼び出しは引数を変更して、基本ケースに向かうようにします。
再帰関数を使うメリット
再帰関数を使う主な利点は、コードの可読性の向上と複雑な問題の分解能力です。
再帰関数は、ループを使用するよりもコードが簡潔で理解しやすくなる場合があります。特に、木構造やグラフなどのデータ構造を扱う場合、再帰関数は非常に役立ちます。
再帰関数は問題を小さな部分に分割し、それぞれを個別に解決することが可能です。これは"divide and conquer"(分割統治)という戦略に基づいています。
再帰関数を実装
それでは、Next.jsとTypeScriptを使用して、再帰関数の実装例を見てみましょう。ここでは、再帰を使用して階乗を計算する関数を作成します。
階乗とは、自然数nの階乗(n!)は、1からnまでの全ての自然数の積を指します。例えば5の階乗(5!)は、1 * 2 * 3 * 4 * 5 = 120
となります。
これを再帰的に解決するには、次のように考えることができます。ある数nの階乗は、nと(n-1)の階乗の積と等しいと言えます。つまり、n! = n * (n-1)!
です。これを利用して、再帰関数を用いて階乗を計算する関数を実装します。
type FactorialProps = {
num: number
}
const FactorialComponent = ({ num }: FactorialProps) => {
const factorial = (n: number): number => {
if (n === 0) return 1;
else return n * factorial(n - 1);
}
return <div>{`The factorial of ${num} is ${factorial(num)}`}</div>
}
このソースコードは、FactorialComponent
というコンポーネントで、num
というpropsを受け取ります。そして、factorial
という再帰関数を定義しています。
この再帰関数は次のように動作します。
n
が0であれば、1を返します。これが基本ケース(終了条件)です。- それ以外の場合は、
n
とn - 1
の階乗の積を返します。これが再帰ケースです。
この結果、FactorialComponent
は指定された数値の階乗を計算し、その結果を表示します。
このように、再帰関数を用いることで、複雑な問題をよりシンプルな形に分割し、解決することができます。また、再帰関数は可読性が高く、複雑なデータ構造を簡潔に表現するのに役立つため、多くのプログラミング言語で広く利用されています。一方で、再帰の深度が非常に深い場合や、基本ケースに到達しない場合などはスタックオーバーフローを引き起こす可能性があるため、適切な使い方と理解が必要です。