パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

再帰呼び出し、よく使う?使わない?」記事へのコメント

  • by Anonymous Coward on 2015年02月11日 18時49分 (#2759489)

    ロジックを設計した段階で再帰的になってれば再帰呼び出しで実装するし
    ロジックを設計した段階で単純ループになってればループ構造で実装する。

    そのように考える方が分かりやすいからそういうロジック設計になっているのだし
    リソースが潤沢な時代だからどっちでもいい。

    • by plauda (46850) on 2015年02月11日 21時12分 (#2759582)

      趣味では使うが、仕事では積極的に使わない。
      ハイエンドのマシンを使う顧客とか、ピーク時でギリギリ扱えるぐらいの余力だったりする。
      やはり、リソースが潤沢という前提が成り立つかどうかかが、業務などの環境依存なので環境依存のコードを入れるのは避けたいところ。

      色んな顧客がいて、負荷がかかるコンポーネントも少しずつ違うし、負荷特性の違う顧客にそれぞれの顧客に対して、
      再起呼び出しで使うスタックサイズが十分であることを保証し続けることが面倒。

      顧客のシステムが運用中にスタックオーバフローで落ちるとか目も当てられないので、
      まずは、見積もり式が必要になるが、これを作成し、メンテナンスし続けるのが手間。
      再起関数を修正すると、必要なスタックサイズも変更になるし、その度に再見積もりさせる訳にもいかない。
      というより、再起呼び出しを使わなくても、スタックに置くデータサイズには気を使う。
      ヒープ見積もりも、見積もりしやすいようにデータ構造の管理方法とか工夫しているくらい。

      親コメント
      • by Anonymous Coward

        これ。再起呼び出しの使いづらさは、「スタックの使用量の見積と確保が困難」という点に尽きる。

    • by Anonymous Coward on 2015年02月11日 19時24分 (#2759511)

      とはいえスタックサイズを過信しないほうがよいと思う。

      親コメント
      • by Anonymous Coward

        ヒープと違ってスタックサイズは潤沢とは言えないですよね。特にデフォルト値。

    • by Anonymous Coward

      計算量O(N)以上のアルゴリズムの実装には再帰を使わない方がいいよ。リソースが膨大でも実際にスタックとして確保されるメモリは多くない。たかだか1〜10MB
      末尾再帰以外の再帰呼出しは関数型言語でも基本的にスタックを消費する。

      • > 計算量O(N)以上のアルゴリズムの実装には再帰を使わない方がいいよ。

        クイックソート(ピボットより小さい側と大きい側の二つ)とか、木のトラバース(2分木なら左の枝と右の枝)といった「自分自身を2回以上呼び出す」ような分割統治されたコードを書くときは、まず再帰を使いますね。末尾再帰とかループ化は簡単にはできません。
        自前でキューとか作って管理すれば再帰を無くせますが、可読性が格段に落ちますし。そんなことをするぐらいなら、関数呼び出しの引数を最小化する(データ本体は別に持たせて、参照のインデックスだけ再帰呼び出しの引数にする)などといったスタック消費量削減を目指した方が楽かと。

        #クイックソートも計算量O(N logN)で、O(N)より大きいよ。ていうか、「計算量がO(N)より小さい」ような「再帰を使う」アルゴリズムってめったにないよなぁ。
        #二分探索ぐらいかですかね?。あれこそ再帰を使うのがばからしいというか、簡単に再帰無しのループに書き下せる感じだけど…

        まあ、2回呼び出しがあるからといってフィボナッチを再帰で組むヤツがいたとしたら、そいつはさすがに許せないな。

        親コメント
        • by Anonymous Coward

          > 計算量がO(N)より小さい」ような「再帰を使う」アルゴリズムってめったにないよなぁ。

          B木ですかねO(log N)。ループだと面倒な気がする。
          あと連続して使うとするとO(N log N)ですが。

      • by Anonymous Coward

        この意見に100%同意。
        逆に再帰を使わずに線形オーダーを対数オーダーに下げる実装をするには、自前で
        スタックや木などのデータ構造を用意しなくてはいけない。

        だから、情報工学やプログラミングのカリキュラムとしては、
        ループ使ったプログラミング→スタックなどのプログラムの動作原理→計算量の概念→再帰を使ったプログラミング
        であればいいと思う。

    • by Anonymous Coward

      自分もロジックによって変えるに一票、というか考えた通り自然に実装するのであまり意識しない。
      もちろん#2759511の通りスタックサイズなどの制約があれば別。

    • by Anonymous Coward

      記述がシンプルになる方を選ぶかな。

    • by Anonymous Coward

      そのように考える方が分かりやすいからそういうロジック設計になっている

      これは、おっしゃる通りだと思います。
      再帰も、ループも、どちらも単なる(考える/機能を実現する)道具でしかないので、「使い分け」るだけという事ですよね ?

      # この基本的な部分には合意した上で、敢えて反論すると..

      ロジックを設計した段階で再帰的になってれば再帰呼び出しで実装する

      は、ちょっとだけ違うのではないかなと...

      思うに、「設計」と「実装」では、立場が違うのではないかと思います。

      (「現状(ここでは C 言語で表現する事を想定..)」では..) 再帰(の実装)は、ループ(の実装)の(機能的な..)上位互換になっています。
      ( #2759525 [developers.srad.jp]) で、ご指摘があったように、ループは

「科学者は100%安全だと保証できないものは動かしてはならない」、科学者「えっ」、プログラマ「えっ」

処理中...