再帰関数はみんな知っていますよね?しかし、関数を再帰的にするのは正確には何ですか? 別の質問 ( JavaScript によるライトニング効果)のコメント セクションでちょっとした議論がありましたが、これは再帰関数に対する私の見方に異議を唱えるものでしたが、適切な定義が不十分であるという不満も残されました。
これまでの再帰関数の個人的な定義は次のとおりです。
直接的または間接的に自分自身を呼び出す場合、関数は再帰的です
注:以下の例では JavaScript コードを提供しますが、それらは非常に普遍的なものであると確信しています。
このような再帰関数の簡単な例は次のとおりです。
function a() {
a();
}
しかし、これも:
function a() {
b();
}
function b() {
a();
}
またはこれさえ:
function a() {
setTimeout(a, 1000);
}
これらの関数はどれも何も計算しませんが、自分自身を呼び出すという理由だけで再帰的であると考えていました。
思いついたことの 1 つは、3 番目の例は再帰的ではないということsetTimeout
です。また、 th 呼び出しから戻った後、n
th 呼び出しに制御を返さないため、再帰的ではありませんn-1
。
提起された別のポイントは、これらの関数はすべて再帰的な方法で実際の問題を計算しないため、再帰的ではないということでした。問題をより小さなインスタンスに分割して解決する必要があることを意味します。引用されたウィキペディアの記事は次のとおりです。
コンピューター プログラミングにおける再帰は、関数がそれ自体のより単純な、多くの場合小さいバージョンの観点から定義されている場合に例証されます。問題の解決策は、問題のより単純なバージョンから得られた解決策を組み合わせることによって考案されます。
したがって、これは再帰的です。
function fac(n) {
if (n <= 0) {
return 1;
}
return n * fac(n - 1);
}
しかし、これはそうではありません:
function fac(n) {
if (n <= 0) {
return 1;
}
console.log(n);
fac(n - 1);
}
それでは、再帰関数の適切な定義は何ですか? まったくあるのでしょうか、それとも本当に単なる哲学的な問題なのでしょうか? 関数が再帰的であると分類されるためには、どのような機能が必要ですか?