再帰とループ


同じ問題を複数回計算する必要がある場合、通常は再帰またはループを選択できます.
関数の直接または間接呼び出し自体が再帰です
  • には、再帰出口と呼ばれる明確な再帰終了条件が必要です.そうしないと、無限に呼び出されます(デッドサイクルに相当します).
  • 再帰には、境界条件、再帰前進セグメント、および再帰帰還セグメントが必要である.
  • 境界条件が満たされない場合、再帰的に前進する.境界条件が満たされると、再帰的に返されます.

  • 再帰関数の実行には多くの回数の関数呼び出しが必要で、毎回新しい変数を作成し、追加のスタック処理を追加する必要があり、実行効率に一定の影響を与え、メモリリソースを消費しすぎます.再帰的に深さ制限があり、呼び出し階層が深すぎると、関数がスタックを繰り返し押すと、スタックメモリがオーバーフローします.
    2つの小さな例を見てみましょう.
    ①nの階乗を求めて、例えば5!=5*4*3*2*1
    まず循環方式で実現する:
    def fn(n,s=1):
        for i in range(1,n+1):
             s *=i
        return s

    再帰的に実現:
    def fn(n):
        if n ==1:           #      
            return n
        return n*fn(n-1)   
    #fn(5)= 5*fn(4) = 5*4*fn(3) = 5*4*3*fn(2) = 5*4*3*2*fn(1) = 5*4*3*2*1
      
    #         
    def fn(n,s=1):
        if n=1:
            return s
        else:
            return fn(n-1,s*n)     #                
    
    #fn(5,1)=>fn(4,5)=>fn(3,20)=>fn(2,60)=>fn(1,120)=>120

    2サルは初日に桃をいくつか摘んで、すぐに半分食べて、まだ食欲をそそらないで、また1つ多く食べました.翌日、残りの桃の半分を食べて、まだ中毒にならないで、また1つ多く食べました;これからは毎日前日の残りの半分余りを食べ、10日目に食べたいときは桃が1つしか残っていません.初日に桃を何個摘んだか聞いてみましょう.
    サイクルで実現:
    def peach(day=10,s=1):
        for i in range(day-1):
            s = (s+1)*2
        return s
    peach()
    
    #    :1534

    再帰的に解く:
    def peach(day=1):
        if day==10:           #      
            return 1
        return (peach(day+1)+1)*2
    
    #    :1534
    #         :
    
    def peach(day=10,s=1):
        if day==1:
            return s
        return peach(day-1,(s+1)*2)   #                  
    peach()
    
    #    :1534