web-dev-qa-db-ja.com

すべての再帰関数を反復でコーディングできますか?

再帰の利点は何ですか?

一部のプログラミング言語は末尾再帰を最適化できますが、一般的な用語では、再帰は通常のループよりも多くのリソースを消費します。

いくつかの再帰関数の反復バージョンを持つことは可能ですか?

10
OscarRyz

はい、再帰関数を反復としてコーディングできます。基本的に、そうでなければコンパイラーによって生成されたコードを呼び出すメソッドによって処理されていたはずの情報を手動で保守する必要があります。

つまり、各エントリが、渡されたパラメータとすべてのローカル変数を含む構造であるスタックが必要です。常にスタックの一番上のエントリで作業します。自分を呼び出す必要がある場合は、新しいエントリを作成してスタックの一番上に置きます。完了したら、スタックの最上位のエントリを取得し、下のエントリを公開し、以前の最上位のエントリを使用して戻り値を抽出し、それに応じて新しい最上位のエントリを更新します。

これが通常マシンコードでどのように実装されているかを確認するために、コンパイラの本を研究することをお勧めします。

10
user1249

多くの場合、再帰は反復よりも物事をより自然に見る方法です。たとえば、バイナリツリーの順序トラバーサルを考えてみます。inorder(left); process(); inorder(right);は、スタックを明示的に維持するよりもはるかに単純です。

深く掘り下げない限り(スタックを吹き飛ばして)、リソース使用量の違いは通常、取るに足らないものです。一般的には心配しないでください。例外はありますが、通常、単純なコードは手動で最適化されたコードよりも優れています。権利は通常、高速よりも優れています。

再帰アルゴリズムは反復アルゴリズムとして表現できますが、明示的にスタックを保持する必要がある場合があります(暗黙的に処理される呼び出しスタックに対応)。結局のところ、再帰的な関数をコンパイルすると、スタックの操作と関数のループ処理に依存するものが得られ、それは反復的です。

末尾再帰関数はループに簡単に変換でき、スタックは必要ありませんが、それは特殊なケースです。

15
David Thornley

再帰の利点は何ですか?

ハノイの塔の問題を繰り返し解決してみてください。あきらめたら、 反復解 を見て、再帰的解と比較してください。どちらが簡単ですか?

いくつかの再帰関数の反復バージョンを持つことは可能ですか?

はい、原則として。ただし、ツリートラバーサルなどの非常に一般的なタスクを含む多くの問題では、再帰的なソリューションは反復的なソリューションよりもはるかに単純でエレガントです。

4
Dima

再帰の利点は何ですか?

Simplicity。末尾呼び出しの最適化なしでは、当然より多くのリソース(スタック)が必要になりますが、たとえばdeltree in Java recursionなしでどのように実装しますか?ツイストはそのdelete()は、ディレクトリが空の場合にのみディレクトリを削除できます。これは再帰付きです。

deltree(File fileOrDirectory) {
    if (fileOrDirectory.isDirectory()) {
        for (File subFileOrDirectory : fileOrDirectory.listFiles()) {
            deltree(subFileOrDirectory);
        }
    }
    fileOrDirectory.delete();
}
3
Joonas Pulakka

再帰は、プログラマーが必須を使用するために必要なツールの1つだと思います。再帰を使用すると、アルゴリズムを「考え」、考えたとおりにアルゴリズムを解くことができます。しかし、私はあなたに警告しなければなりません、私が言うべきいくつかのことに関して、誰もが再帰がいかに素晴らしいか、そしてコードがどれほど単純になるかについて話している:

  1. まず、アルゴリズムの「再帰的な方法」を考えるのは簡単ではありません。階乗(n!)のような関数やハノイの塔のようなものを構築することは、氷山の一角に過ぎず、底に到達するには長い時間がかかります。
  2. 再帰がコードに単純さをもたらすだけだとは思わないでください。反復的な方法は見苦しく面倒ですが、費用効果が高いです(フィボナッチ問題の再帰的解決策を調べてください)。

それらを念頭に置いて、再帰を学びましょう!それはおかしく、複雑で、脳を壊します!しかし、あなたはそれを愛していることに気付くでしょう。

がんばって!

0
David Conde