web-dev-qa-db-ja.com

再帰の実世界の例

深さ優先探索(DFS)に加えて再帰的アプローチが自然な解決策である現実世界問題とは何ですか?

ハノイの塔フィボナッチ数 、または要因の現実世界の問題は考慮しません。それらは私の頭の中では少し不自然です。)

85
redfood

ここにはたくさんの素敵な例がありますが、現実の世界の例が欲しかったので、少し考えてみると、これはおそらく私が提供できる最高のものです:

致命的ではない特定の感染症にかかった人を見つけます。これは致命的ではなく、すぐに直ります症状と単にスプレッダーとして機能します。

これにより、タイプBがタイプAの多数に感染すると、非常に迷惑な波が作成されます。

あなたの仕事は、すべてのタイプBを追跡し、それらを免疫して病気の背骨を止めることです。残念なことに、typeAsの人たちはB型に有効な治療法に対して致命的なアレルギーがあるため、すべての人に全国的な治療法を施すことはできません。

あなたがこれを行う方法は、感染者(タイプA)を与えられた社会的発見であり、先週のすべての連絡先を選択し、各連絡先をヒープにマークします。人が感染していることをテストするとき、それらを「フォローアップ」キューに追加します。人物がタイプBの場合、頭の「フォローアップ」に追加します(これを早く止めたいので)。

特定の人を処理した後、キューの先頭からその人を選択し、必要に応じて予防接種を適用します。以前に訪問したことのない連絡先をすべて取得し、感染しているかどうかをテストします。

感染者のキューが0になるまで繰り返し、その後、別のアウトブレークを待ちます。

(OK 、そして私はそれが本能的になるようにどこでも再帰を強制的に削除します.....くそ!)

32
Kent Fredric

再帰の実世界の例

A sunflower

105
Hans Sjunnesson

ファイルシステムのディレクトリ構造に関係するものはどうですか。再帰的なファイルの検索、ファイルの削除、ディレクトリの作成など。

ディレクトリとそのサブディレクトリの内容を再帰的に出力するJava実装です。

import Java.io.File;

public class DirectoryContentAnalyserOne implements DirectoryContentAnalyser {

    private static StringBuilder indentation = new StringBuilder();

    public static void main (String args [] ){
        // Here you pass the path to the directory to be scanned
        getDirectoryContent("C:\\DirOne\\DirTwo\\AndSoOn");
    }

    private static void getDirectoryContent(String filePath) {

        File currentDirOrFile = new File(filePath);

        if ( !currentDirOrFile.exists() ){
            return;
        }
        else if ( currentDirOrFile.isFile() ){
            System.out.println(indentation + currentDirOrFile.getName());
            return;
        }
        else{
            System.out.println("\n" + indentation + "|_" +currentDirOrFile.getName());
            indentation.append("   ");

            for ( String currentFileOrDirName : currentDirOrFile.list()){
                getPrivateDirectoryContent(currentDirOrFile + "\\" + currentFileOrDirName);
            }

            if (indentation.length() - 3 > 3 ){
                indentation.delete(indentation.length() - 3, indentation.length());
            }
        }       
    }

}
64
Matt Dillard

クイックソートマージソート 、および他のほとんどのN-log Nソート。

44
BCS

マット・ディラードの例は良いです。より一般的には、ツリーを歩くことは一般に再帰によって非常に簡単に処理できます。たとえば、解析ツリーのコンパイル、XMLまたはHTMLの探索など。

16
Cody Brocious

再帰は、 バックトラッキングアルゴリズム の実装でよく使用されます。この「現実の」アプリケーションの場合、 数独ソルバー

16
bkane

再帰は、問題をサブ問題に分割することで解決できる場合に適切であり、サブ問題は同じ問題を解決するために使用できます。ツリーおよびソートされたリストのアルゴリズムは自然に適合します。計算ジオメトリ(および3Dゲーム)の多くの問題は、 バイナリ空間分割 (BSP)ツリー、 脂肪の細分化 、または世界をサブに分割する他の方法を使用して再帰的に解決できます。部品。

アルゴリズムの正確性を保証しようとしている場合にも、再帰は適切です。不変の入力を受け取り、入力に対する再帰呼び出しと非再帰呼び出しの組み合わせである結果を返す関数を考えると、数学的な帰納法を使用して、関数が正しい(または正しくない)ことを簡単に証明できます。多くの場合、これを反復関数や、変化する可能性のある入力で行うのは困難です。これは、財務計算や、正確性が非常に重要な他のアプリケーションを扱うときに役立ちます。

13
Sam

確かに多くのコンパイラが再帰を頻繁に使用しています。コンピューター言語は本質的に再帰的です(つまり、「if」ステートメントを他の「if」ステートメントなどに埋め込むことができます)。

11
Martin Cote

コンテナコントロール内のすべての子コントロールの読み取り専用の無効化/設定。子コントロールの一部がコンテナそのものだったため、これを行う必要がありました。

public static void SetReadOnly(Control ctrl, bool readOnly)
{
    //set the control read only
    SetControlReadOnly(ctrl, readOnly);

    if (ctrl.Controls != null && ctrl.Controls.Count > 0)
    {
        //recursively loop through all child controls
        foreach (Control c in ctrl.Controls)
            SetReadOnly(c, readOnly);
    }
}
9
chitza

[〜#〜] sicp [〜#〜] からの有名な評価/適用サイクル

alt text
(ソース: mit.ed

Evalの定義は次のとおりです。

(define (eval exp env)
  (cond ((self-evaluating? exp) exp)
        ((variable? exp) (lookup-variable-value exp env))
        ((quoted? exp) (text-of-quotation exp))
        ((assignment? exp) (eval-assignment exp env))
        ((definition? exp) (eval-definition exp env))
        ((if? exp) (eval-if exp env))
        ((lambda? exp)
         (make-procedure (lambda-parameters exp)
                         (lambda-body exp)
                         env))
        ((begin? exp) 
         (eval-sequence (begin-actions exp) env))
        ((cond? exp) (eval (cond->if exp) env))
        ((application? exp)
         (apply (eval (operator exp) env)
                (list-of-values (operands exp) env)))
        (else
         (error "Unknown expression type - EVAL" exp))))

適用の定義は次のとおりです。

(define (apply procedure arguments)
  (cond ((primitive-procedure? procedure)
         (apply-primitive-procedure procedure arguments))
        ((compound-procedure? procedure)
         (eval-sequence
           (procedure-body procedure)
           (extend-environment
             (procedure-parameters procedure)
             arguments
             (procedure-environment procedure))))
        (else
         (error
          "Unknown procedure type - APPLY" procedure))))

Eval-sequenceの定義は次のとおりです。

(define (eval-sequence exps env)
  (cond ((last-exp? exps) (eval (first-exp exps) env))
        (else (eval (first-exp exps) env)
              (eval-sequence (rest-exps exps) env))))

eval-> apply-> eval-sequence-> eval

8
jfs

再帰は、ゲーム開発(および他の同様の分野)での衝突検出のためにBSPツリーなどで使用されます。

7
Mark

多くの場合、再帰的な方法を使用してドキュメントのスタックをソートします。たとえば、名前の付いた100個のドキュメントをソートしているとします。最初に最初の文字で文書を山に配置し、次に各山を並べ替えます。

辞書内の単語の検索は、多くの場合、再帰的なバイナリ検索のような手法によって実行されます。

組織では、上司が部門長にコマンドを与え、部門長がマネージャーにコマンドを与えることなどがよくあります。

7
tkerwin

再帰は、問題(状況)に適用され、それをより小さな部分に分割(削減)することができ、各部分は元の問題に似ています。

それ自体に似た小さな部分を含むものの良い例は次のとおりです。

  • ツリー構造(ブランチはツリーのようなものです)
  • リスト(リストの一部はまだリストです)
  • コンテナ(ロシアの人形)
  • シーケンス(シーケンスの一部は次のようになります)
  • オブジェクトのグループ(サブグループは依然としてオブジェクトのグループです)

再帰とは、問題をさらに小さな断片に分割し、それらの断片の1つがケーキの断片になるほど小さくなるまで続ける手法です。もちろん、それらを分割した後、元の問題の完全な解決策を形成するために、正しい順序で結果を「ステッチ」する必要があります。

いくつかの再帰的ソートアルゴリズム、ツリーウォークアルゴリズム、map/reduceアルゴリズム、分割統治法はすべてこの手法の例です。

コンピュータープログラミングでは、ほとんどのスタックベースのコールリターン型言語には、再帰用の機能が既に組み込まれています。

  • 問題をより小さな部分に分解します==>元のデータのより小さなサブセットでそれ自体を呼び出します)、
  • ピースの分割方法を追跡する==>コールスタック、
  • 結果をステッチバック==>スタックベースのリターン
4
Stephen Chung

関数型プログラミング 言語には、再帰のすばらしい例がいくつかあります。関数型プログラミング言語( ErlangHaskell[〜#〜] ml [〜#〜] / OCaml / F# など)、リスト処理で再帰を使用することは非常に一般的です。

典型的な命令型OOPスタイルの言語でリストを処理する場合、リンクリストとして実装されたリストを見るのは非常に一般的です([item1-> item2-> item3-> item4])。ただし、一部の関数型プログラミング言語では、リスト自体が再帰的に実装されており、リストの「ヘッド」はリストの最初のアイテムを指し、「テール」は残りのアイテムを含むリストを指します( [item1-> [item2-> [item3-> [item4-> []]]]])。私の意見ではかなり創造的です。

このリストの処理は、パターンマッチングと組み合わせると非常に強力です。数字のリストを合計したいとしましょう:

let rec Sum numbers =
    match numbers with
    | [] -> 0
    | head::tail -> head + Sum tail

これは基本的に「空のリストで呼び出された場合、0を返します」(再帰を中断できるようにします)、またはheadの値+残りの項目で呼び出されたSumの値を返します(したがって、再帰)。

たとえば、 RLs のリストがあり、各URLがリンクするすべてのURLを分解し、すべてのURLへの/からのリンクの総数を減らして、ページ(Googleが PageRank で採用し、元の MapReduce の論文で定義されているアプローチ)これを行うと、ドキュメント内のワードカウントも生成できます。そして、他にも多くの、多くの、多くのこと。

この機能パターンは、任意のタイプの MapReduce コードに拡張できます。このコードでは、何かのリストを取得して変換し、別のリスト(別のリストまたはリスト上のZipコマンド)を返すことができます。

4
Jason Olson

私が最近得た実世界の要件:

要件A:要件Aを完全に理解した後、この機能を実装します。

4
dragon

パーサーとコンパイラーは、再帰降下法で記述できます。 Lex/yaccのようなツールはより高速で効率的なパーサーを生成するため、これを行う最適な方法ではありませんが、概念的にはシンプルで実装しやすいため、一般的なままです。

4
davenpcj

ステートマシンをシミュレートするために、いくつかの場所で純粋な tail recursion を使用するシステムがあります。

4
BCS

XML、またはツリーであるあらゆるものを横断する。正直なところ、仕事で再帰を使用することはほとんどありません。

3
Charles Graham

階層組織のフィードバックループ。

トップボスは、トップエグゼクティブに社内の全員からフィードバックを収集するよう指示します。

各エグゼクティブは、直属の部下を集めて、直属部下からフィードバックを集めるように指示します。

そして、今後は。

直属の部下のいない人(ツリーのリーフノード)がフィードバックを提供します。

フィードバックは、各マネージャーが自分のフィードバックを追加してツリーを遡ります。

最終的にすべてのフィードバックは、トップボスに戻ります。

これは自然な解決策です。再帰的な方法では、重複の照合と不快なフィードバックの除去といった各レベルでのフィルタリングが可能です。トップボスcouldグローバルメールを送信し、各従業員にフィードバックを直接報告しますが、「真実を処理できない」という問題と「解雇された」という問題があります。 、ここで再帰が最適に機能します。

3
Mark

複合平均などの金融/物理学の計算。

2
Apocalisp

私が知っている最良の例は quicksort であり、再帰の方がずっと簡単です。を見てみましょう:

shop.oreilly.com/product/9780596510046.do

www.Amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047

(第3章「最初に書いた最も美しいコード」の下の最初のサブタイトルをクリックしてください)。

2
Fabio Ceconello
  • [〜#〜] xml [〜#〜] ファイルの解析。
  • 多次元空間での効率的な検索。例2Dのクアッドツリー、3Dのオクトツリー、kdツリーなど.
  • 階層的なクラスタリング。
  • 考えてみると、階層構造をたどることは自然に再帰に役立ちます。
  • C++のテンプレートメタプログラミング。ループはなく、再帰が唯一の方法です。
2
Dima

あなたがあなたのページがツリー構造にあるウェブサイトのためにCMSを構築していると仮定してください。例えば、ルートはホームページです。

また、{user | client | customer | boss}がすべてのページにパンくずリストを配置して、ツリーのどこにいるかを表示するように要求するとします。

任意のページnについて、nの親、およびその親まで再帰的に歩いて、ページツリーのルートに戻るノードのリストを作成することができます。

もちろん、この例ではページごとにdbを数回ヒットしているので、ページテーブルをaとして検索し、ページテーブルを再びbとして検索し、a.idと結合するSQLエイリアスを使用することができますb.parentを使用すると、データベースに再帰結合を実行させることができます。久しぶりなので、私の構文はおそらく役に立たないでしょう。

繰り返しになりますが、これは一度だけ計算してページレコードに保存し、ページを移動した場合にのみ更新することができます。それはおそらくより効率的です。

とにかく、それは私の$ .02です

2
Sam McAfee

Nレベルの深さの組織ツリーがあります。いくつかのノードがチェックされており、チェックされたノードのみに展開したい場合。

これは実際にコーディングしたものです。その素敵で簡単な再帰。

2
MagicKat

Windows Forms またはWebForms(.NET Windows Forms/ ASP.NET )でコントロールのツリーを解析します。

2
Andrei Rînea

私の仕事には、ツリーとして記述できる一般的なデータ構造を持つシステムがあります。つまり、再帰はデータを操作するための非常に効果的な手法であることを意味します。

再帰なしで解決するには、多くの不必要なコードが必要になります。再帰の問題は、何が起こるかを追跡するのが簡単ではないことです。実行の流れに従う場合、本当に集中する必要があります。しかし、それが機能するとき、コードはエレガントで効果的です。

2
Tommy

反復を使用するすべての処理は、スタックオーバーフローを引き起こす実際的な制限がない限り、再帰によってより自然に行われます;-)

しかし、真剣に再帰と反復は非常に互換性があり、再帰を使用してすべてのアルゴリズムを書き換えて反復を使用したり、その逆を行うことができます。数学者は再帰を好み、プログラマーは反復を好みます。それがおそらく、あなたが言及するこれらの不自然な例をすべて見る理由でもあります。数学帰納法と呼ばれる数学的証明の方法は、数学者が再帰を好む理由があると思います。 http://en.wikipedia.org/wiki/Mathematical_induction

1
Remco

自然数の乗算は、再帰の実際の例です。

To multiply x by y
  if x is 0
    the answer is 0
  if x is 1
    the answer is y
  otherwise
    multiply x - 1 by y, and add x
1
Apocalisp

素数を見つける方法は再帰的です。多数の因子を使用するさまざまな暗号化スキームで、ハッシュキーを生成するのに役立ちます。

1
Apocalisp

電話会社とケーブル会社は、実際には大規模なネットワークまたはグラフである配線トポロジのモデルを維持しています。すべての親要素またはすべての子要素を検索する場合、再帰はこのモデルを走査する1つの方法です。

再帰は処理とメモリの観点から高価であるため、この手順は通常、トポロジが変更され、結果が修正済みの事前順序付きリスト形式で保存される場合にのみ実行されます。

1
Steve Moyer

帰納的推論、概念形成のプロセスは、本質的に再帰的です。現実の世界では、あなたの脳は常にそれを行います。

1
Apocalisp

ほとんどの再帰は、再帰的なデータ構造を扱うために非常に自然です。これは基本的にリスト構造とツリー構造を意味します。しかし、再帰は、たとえば quicksort またはバイナリ検索などの分割統治による、何らかの方法でオンザフライでツリー構造を作成/作成するニースの自然な方法でもあります。

あなたの質問はある意味で少し見当違いだと思います。深さ優先検索の実世界ではないものは何ですか?深さ優先検索でできることはたくさんあります。

たとえば、私が考えたもう1つの例は、再帰降下コンパイルです。多くの実世界のコンパイラで使用されているのは、実世界の問題で十分です。しかし、あなたはそれがDFSであると主張することができます。それは基本的に有効な解析ツリーの深さ優先探索です。

1

かつて再帰なしで書くのははるかに困難であったXMLパーサーを書きました。

スタック+イテレーションを常に使用できると思いますが、再帰が非常にエレガントな場合もあります。

1
dicroce

ツリーまたはグラフのデータ構造を持つプログラムには、何らかの再帰があります。

1
Mark Harrison

平均ケースO(n)の中央値を見つける。 n個の物のリストからk番目に大きいアイテムを見つけることに相当します。k= n/2を使用します。

ここで、partitionはピボット要素を選択し、データを1回通過して、ピボットよりも小さいアイテムが最初に、次にピボット、次にピボットよりも大きいアイテムが最初に来るようにリストを再配置します。 「kthLargest」アルゴリズムはクイックソートに非常に似ていますが、リストの片側のみで再帰します。

私にとって、これは反復アルゴリズムよりも高速に実行される最も単純な再帰アルゴリズムです。 kに関係なく、平均で2 * nの比較を使用します。これは、kを実行してデータを通過させ、毎回最小値を見つけて破棄するという単純なアプローチよりもはるかに優れています。

アレホ

1
user37968

コンパイラに関するコメントも同様です。抽象構文ツリーのノードは、当然のことながら再帰に役立ちます。再帰的なデータ構造(リンクリスト、ツリー、グラフなど)もすべて、再帰を使用して簡単に処理できます。私たちのほとんどは、現実世界の問題の種類のために、学校を卒業すると再帰をあまり使用しないと思いますが、オプションとしてそれを認識することは良いことです。

1
origin

12345.67のような数値を「12ドル345ドルと67セント」に変換する関数を記述します。

1
Robert Rossney
  1. 大学の貯蓄プラン:A(n) = nか月後に大学のために節約された金額A(0) = $ 500毎月、$ 50は年間利息で5%を獲得するアカウント。

次にA(n) = A(n-1) + 50 + 0.05*(1/12)* A(N-1)

0
joe_n

C#でツリーを作成して、デフォルトケースの6セグメントキー(key [0]が存在しない場合は、デフォルトケースを使用して続行)を持つテーブルのルックアップを処理します。ルックアップは再帰的に行われました。辞書などの辞書の辞書を試してみましたが、非常に複雑になりました。

また、ツリーに格納された方程式を評価して評価順序を正しくするC#の数式エバリュエーターを作成しました。確かに、これは問題に対して間違った言語を選択する場合である可能性がありますが、興味深い演習でした。

私は人々がしたことの多くの例を見たのではなく、むしろ彼らが使用したライブラリを見ました。うまくいけば、これがあなたに何か考えさせることを与えてくれます。

0
Austin Salonen

Subsonicを使用して、データベーステーブルからツリー構造のメニューを生成する方法。

public MenuElement(BHSSiteMap node, string role)
    {
        if (CheckRole(node, role))
        {
            ParentNode = node;

            // get site map collection order by sequence
            BHSSiteMapCollection children = new BHSSiteMapCollection();

            Query q = BHSSiteMap.CreateQuery()
                    .WHERE(BHSSiteMap.Columns.Parent, Comparison.Equals, ParentNode.Id)
                    .ORDER_BY(BHSSiteMap.Columns.Sequence, "ASC");

            children.LoadAndCloseReader(q.ExecuteReader());

            if (children.Count > 0)
            {
                ChildNodes = new List<MenuElement>();

                foreach (BHSSiteMap child in children)
                {
                    MenuElement childME = new MenuElement(child, role);
                    ChildNodes.Add(childME);
                }
            }
        }
    }
0

円のエッジの検索など、GISまたは地図作成のための幾何学的計算。

0
Apocalisp

平方根を見つける方法は再帰的です。現実世界の距離を計算するのに便利です。

0
Apocalisp

私が持っている最後の実世界の例はかなり軽薄ですが、それは再帰がときどき「ジャストフィット」する方法を示しています。

Chain of Responsibilityパターンを使用していたため、Handlerオブジェクトはリクエスト自体を処理するか、チェーンに沿って委任します。チェーンの構築を記録すると便利です。

public String getChainString() {
    cs = this.getClass().toString();
    if(this.delegate != null) {
        cs += "->" + delegate.getChainString();
    }
    return cs;
}

メソッドは「それ自体」を呼び出しますが、呼び出されるたびに異なるインスタンスにあるため、これは最も純粋な再帰ではないと主張できます。

0
slim

建物があります。建物には20室の部屋があります。法的には、各部屋に一定の人数しか入れることができません。あなたの仕事は、人々を部屋に自動的に割り当てることです。部屋がいっぱいになったら、空いている部屋を見つける必要があります。特定の部屋だけが特定の人を収容できることを考えると、どの部屋に注意する必要もあります。

例えば:

ルーム1、2、3は互いにロールインできます。この部屋は自分で歩くことができない子供のためのものであるため、気を散らすことや他の病気を避けるために他のすべてのものから離れて欲しいです(これは高齢者にとっては問題ではありませんが、6カ月では非常に悪くなる可能性があります。 3つすべてがいっぱいになると、その人は入場を拒否されなければなりません。

ルーム4、5、6は互いにロールインできます。この部屋はピーナッツにアレルギーのある人のためのものであり、したがって、彼らは他の部屋(ピーナッツの入ったものがあるかもしれません)には入ることができません。 3つすべてが満杯になった場合は、アレルギーレベルを尋ねる警告を表示し、アクセスを許可することができます。

部屋はいつでも変更できます。したがって、部屋7-14はピーナッツのない部屋にすることができます。チェックする部屋の数がわかりません。

または、おそらく年齢に基づいて分離する必要があります。グレード、性別など。これらは私が出会ったいくつかの例です。

0
Kenny Mann
0
Sebastian Mach

再帰によって解決される「現実の」問題は、入れ子人形です。あなたの関数はOpenDoll()です。

それらのスタックを考えると、あなたは人形を再帰的に開いて、もし望むならOpenDoll()を呼び出し、最も内側の人形に到達するまで続けます。

0

2つの異なるが類似したシーケンスがあり、各シーケンスのコンポーネントを一致させて、大きな連続したチャンクが最初に優先され、次に同じシーケンス順序が続くようにする場合、それらのシーケンスを再帰的に分析してツリーを形成し、そのツリーを再帰的に処理して平坦化することができますそれ。

リファレンス:再帰とメモのサンプルコード

0
Noctis Skytower

DataContractSerializerを使用してクラスをシリアル化する必要があるかどうかを判断するための再帰関数を作成しました。大きな問題は、クラスにdatacontractシリアル化する必要がある他の型が含まれる可能性があるテンプレート/ジェネリックで発生しました...

0
CodeRedick

これらを使用して、SQLパス検索を行います。

また、デバッグするのは骨の折れる作業であり、貧しいプログラマーがそれを台無しにすることは非常に簡単です。

0
www.smackfu.com

再帰は非常に基本的なプログラミング技術であり、それをリストすることは、何らかの追加を使用して解決できるすべての問題をリストするような、非常に多くの問題に役立ちます。 Project EulerのLISPソリューションを調べてみると、クロストータル関数、数字一致関数、スペースを検索するためのいくつかの関数、最小限のテキストパーサー、数字を10進数のリストに分割する関数、関数グラフの構築、および入力ファイルを横断する関数。

問題は、今日のほとんどの主流のプログラミング言語ではなくても、多くが末尾呼び出しの最適化を持たないため、深い再帰を実行できないことです。この不適切さは、ほとんどのプログラマーがこの自然な考え方を学習せず、代わりに他の、おそらくそれほど洗練されていないループ構造に頼らざるを得ないことを意味します。

0
Svante

あなたはコンピュータサイエンスやマチの例が好きではないようですので、ここでは別のものがあります:ワイヤーパズル。

多くのワイヤーパズルでは、ワイヤーリングの内外で作業することにより、ワイヤーの長い閉ループを除去する必要があります。これらのパズルは再帰的です。それらの1つは「矢印ダイナミクス」と呼ばれます。 「矢印ダイナミクスワイヤーパズル」をグーグルで検索すれば見つけることができると私は訴えています

これらのパズルは、ハノイの塔によく似ています。

0
user2474247

作成された画像がサイズ制限ボックス内で機能するかどうかを確認します。

function check_size($font_size, $font, $text, $width, $height) {
        if (!is_string($text)) {
            throw new Exception('Invalid type for $text');
        }   
        $box = imagettfbbox($font_size, 0, $font, $text);
        $box['width'] = abs($box[2] - $box[0]);
        if ($box[0] < -1) {
            $box['width'] = abs($box[2]) + abs($box[0]) - 1;
        }   
        $box['height'] = abs($box[7]) - abs($box[1]);
        if ($box[3] > 0) {
            $box['height'] = abs($box[7] - abs($box[1])) - 1;
        }   
        return ($box['height'] < $height && $box['width'] < $width) ? array($font_size, $box['width'], $height) : $this->check_size($font_size - 1, $font, $text, $width, $height);
    }
0
mk.

これは本当に言語に依存していると思います。一部の言語では、 [〜#〜] lisp [〜#〜] 、たとえば、再帰は問題に対する自然な反応であることがよくあります(多くの場合、これが当てはまる言語では、コンパイラは再帰に対処する)。

リストの最初の要素で操作を実行してから、値または新しいリストを蓄積するためにリストの残りの部分で関数を呼び出すというLISPの一般的なパターンは、非常にエレガントで多くのことを行う最も自然な方法ですその言語でのこと。 Java では、それほどではありません。

0
Paul Wicks