私がこれまでに見た再帰関数に関するすべての教科書は、階乗を例として使用しています。
プログラミングの目的で、再帰関数はその基本ケースとして関数を使用できますか、その本体内に他の関数呼び出しを含めることができますか、または再帰のさまざまなレベルで異なる方法で実行できますか?
そして、これらのいずれかを行う場合、それはまだ「再帰関数」ですか、それとも別のものですか?
私がこれまでに見た再帰関数に関するすべての教科書は、階乗を例として使用しています。
プログラミングの目的で、再帰関数はその基本ケースとして関数を使用できますか、その本体内に他の関数呼び出しを含めることができますか、または再帰のさまざまなレベルで異なる方法で実行できますか?
そして、これらのいずれかを行う場合、それはまだ「再帰関数」ですか、それとも別のものですか?
再帰関数の定義は、単純に「自分自身を呼び出す関数」です。したがって、自分自身を呼び出す関数がある場合、それは再帰関数です。
それ以外は、使用している言語の機能に依存します。
これは、コレクション内のすべての値(スタックとして表される配列)を.pop()メソッドを使用してスタックからポップするときにブラウザーコンソールに出力するだけの再帰関数の非常に単純な例です。
totalSize値は、呼び出しスタック全体で変更されないため、現在のスタックサイズを元のサイズで除算することにより、中間点を測定するために使用できます。
再帰のさまざまなレベルで異なる動作をすることができるかという質問に答えるには、答えは「はい」です。
// a simple array of 10 items
var coll = [1,2,3,4,5,6,7,8,9,10];
// recursive function that calls itself. It behaves slightly different at
// the halfway point
function test(totalSize, col) {
if(col == undefined || col.length == 0) {
return 0;
} else {
if(col.length / totalSize < .5) {
console.log("Past 1/2 way point!");
}
console.log("total = " + totalSize);
console.log("col.pop() = " + col.pop());
return test(totalSize, col);
}
}
// make a call to the function with the total size and the collection
test(coll.length, coll);
さらに、他の関数を呼び出すことが可能かどうかも尋ねましたが、これも可能です。以下の例では、関数を使用して基本ケースの結果を返し、関数を使用して中間点の動作を抽象化します。
// a simple array of 10 items
var coll = [1,2,3,4,5,6,7,8,9,10];
// recursive function that calls itself. It behaves slightly different at
// the halfway point
function test(totalSize, col) {
if(col == undefined || col.length == 0) {
return handleBaseCase(totalSize, col);
} else {
// handle if it's at 1/2 way point
handleHalfwayPoint(totalSize, col);
console.log("tital = " + totalSize);
console.log("col.pop() = " + col.pop());
return test(totalSize, col);
}
}
function handleHalfwayPoint(totalSize, collection) {
if(collection.length / totalSize < .5) {
console.log("Past 1/2 way point!");
}
}
// instead of returning 0, return "Done" and also print to the log
function handleBaseCase(totalSize, collection) {
console.info("Done!");
return "Done!";
}
// make a call to the function with the total size and the collection
test(coll.length, coll);
これらの特定の例は実際の問題を解決しませんが、別の関数内で関数を呼び出すという概念を拡張して、他のユースケースを処理する方法を示しています。教科書の例は、再帰の基本を教え、将来、より複雑な現実の問題に取り組むために必要なツールを身に付けるのに役立つように設計されています。
この関数型言語はJavaScriptであるため、それらを実行する際の障壁は低くなっています。これらの例は、Chromeデベロッパーコンソールでコードを実行することで試すことができます。または、小さなテストHTMLファイルで実行することもできます。幸運を!
再帰関数は、本体で 1 回以上自分自身を呼び出す関数です。関数は、1 つの関数が 2 番目の関数に関して定義されている場合、またはその逆の場合に、相互に再帰的になる場合もあります。
私は再帰を必要とせずに20年以上プログラミングしてきました。再帰呼び出しの必要性と美しさを本当に理解させてくれたのは、Scheme 言語と、「The little Schemer」などの本でした。
すべてのプログラミング言語が同じレベルで再帰をサポートしているわけではありません。スキームは、それを非常にうまく行う人の1人です。Pythonはそうではありません。したがって、再帰に飛び込みたい場合は、プログラミング言語の能力を確認してください。
他の答えが言ったように、再帰関数はそれ自体を呼び出す関数です。ここで説明するように、次の 2 つのタイプがあります。
あなたの質問に数学タグがあります。再帰は数学の誘導に関連しています。基本ケースを解決できることを証明し、無限のステートメント シーケンスのいずれか 1 つのステートメントが真である場合、次のステートメントも真であることを証明すると、どのような場合でも問題を解決できることが証明されます。