再帰とループ
同じ問題を複数回計算する必要がある場合、通常は再帰またはループを選択できます.
関数の直接または間接呼び出し自体が再帰ですには、再帰出口と呼ばれる明確な再帰終了条件が必要です.そうしないと、無限に呼び出されます(デッドサイクルに相当します). 再帰には、境界条件、再帰前進セグメント、および再帰帰還セグメントが必要である. 境界条件が満たされない場合、再帰的に前進する.境界条件が満たされると、再帰的に返されます.
再帰関数の実行には多くの回数の関数呼び出しが必要で、毎回新しい変数を作成し、追加のスタック処理を追加する必要があり、実行効率に一定の影響を与え、メモリリソースを消費しすぎます.再帰的に深さ制限があり、呼び出し階層が深すぎると、関数がスタックを繰り返し押すと、スタックメモリがオーバーフローします.
2つの小さな例を見てみましょう.
①nの階乗を求めて、例えば5!=5*4*3*2*1
まず循環方式で実現する:
再帰的に実現:
2サルは初日に桃をいくつか摘んで、すぐに半分食べて、まだ食欲をそそらないで、また1つ多く食べました.翌日、残りの桃の半分を食べて、まだ中毒にならないで、また1つ多く食べました;これからは毎日前日の残りの半分余りを食べ、10日目に食べたいときは桃が1つしか残っていません.初日に桃を何個摘んだか聞いてみましょう.
サイクルで実現:
再帰的に解く:
関数の直接または間接呼び出し自体が再帰です
再帰関数の実行には多くの回数の関数呼び出しが必要で、毎回新しい変数を作成し、追加のスタック処理を追加する必要があり、実行効率に一定の影響を与え、メモリリソースを消費しすぎます.再帰的に深さ制限があり、呼び出し階層が深すぎると、関数がスタックを繰り返し押すと、スタックメモリがオーバーフローします.
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