再帰の利点は何ですか?
一部のプログラミング言語は末尾再帰を最適化できますが、一般的な用語では、再帰は通常のループよりも多くのリソースを消費します。
いくつかの再帰関数の反復バージョンを持つことは可能ですか?
再帰の利点は何ですか?
一部のプログラミング言語は末尾再帰を最適化できますが、一般的な用語では、再帰は通常のループよりも多くのリソースを消費します。
いくつかの再帰関数の反復バージョンを持つことは可能ですか?
回答:
はい、再帰関数を反復としてコーディングできます。基本的に、手動で情報を維持する必要があります。そうしないと、コンパイラーによって生成されたコードを呼び出すメソッドによって処理されていました。
つまり、各エントリが渡されたパラメータとすべてのローカル変数を含む構造であるスタックが必要です。常にスタックの一番上のエントリで作業します。自分を呼び出す必要がある場合は、新しいエントリを作成してスタックの一番上に置きます。完了したら、スタックの最上位のエントリを取得し、下のエントリを公開し、以前の最上位のエントリを使用して戻り値を抽出し、それに応じて新しい最上位のエントリを更新します。
これが通常マシンコードでどのように実装されているかを確認するために、コンパイラの本を研究することをお勧めします。
多くの場合、再帰は反復よりも物事をより自然に見る方法です。たとえば、バイナリツリーの順序トラバーサルを考えてみ inorder(left); process(); inorder(right);
ます。これは、スタックを明示的に維持するよりもはるかに簡単です。
深く掘り下げない限り(スタックを吹き飛ばして)、リソース使用量の違いは通常、取るに足らないものです。一般的には心配しないでください。例外はありますが、通常、単純なコードは手動で最適化されたコードよりも優れています。権利は通常、高速よりも優れています。
再帰アルゴリズムは反復アルゴリズムとして表現できますが、明示的にスタックを保持する必要がある場合があります(暗黙的に処理される呼び出しスタックに対応)。結局のところ、再帰関数をコンパイルすると、スタックの操作と関数のループ処理に依存するものが得られ、それが反復的です。
末尾再帰関数はループに簡単に変換でき、スタックは必要ありませんが、それは特殊なケースです。
再帰の利点は何ですか?
シンプルさ。もちろん、末尾呼び出しの最適化がなければ、より多くのリソース(スタック)が必要になりますが、たとえば、deltree
再帰なしでJavaにどのように実装しますか?ひねりは、delete()
ディレクトリが空の場合にのみディレクトリを削除できることです。ここに再帰があります:
deltree(File fileOrDirectory) {
if (fileOrDirectory.isDirectory()) {
for (File subFileOrDirectory : fileOrDirectory.listFiles()) {
deltree(subFileOrDirectory);
}
}
fileOrDirectory.delete();
}
再帰は、プログラマーが生きなければならないツールの1つだと思います。再帰を使用すると、アルゴリズムを「考え」、考えたとおりにアルゴリズムを解くことができます。しかし、私はあなたに警告しなければなりません、私が言うべきいくつかのことに関して、誰もがかなり再帰がいかに素晴らしく、コードにどれほど単純さがもたらすかについて話している:
それらを念頭に置いて、再帰を学びましょう!面白くて複雑で、脳を壊すでしょう!
がんばって!