目次
1. 再帰関数
1.コンセプト
再帰関数: 独自の関数を呼び出すことは再帰関数であり
、行ったり来たり、戻ったりします。
2. 特長
関数の実行時には、スタック フレーム スペースと呼ばれるスペースを確保するためにメモリが必要です。
再帰:
(1) 行きのプロセスは、スタック フレーム スペースを継続的にオープンします。戻りの場合、スタック フレーム スペースを継続的に解放します。再帰関数は、スタック フレーム スペースを継続的にオープンおよび解放する完全なプロセスです (
2
) ) 戻るときのトリガー メカニズムは 2 つあります。関数空間の最後の層が完全に実行されるか、底に到達してリバウンドします (カービンに戻ります)。(3) 再帰関数を作成するときは、ジャンプを与える必要があります。
out 条件、再帰の層が多すぎる場合、使用はお勧めできません。メモリ オーバーフローやブルー スクリーンが発生しやすくなります。 (4) 再帰
呼び出しスペースの各層は独立した個別のものであり、独立したコピーであり、リソースは共有されません。 、価値の移転は返品を通じて完了できます
公式には、特にマシンによると、再帰の最大深さは 1000 層です。
def deepfunc():
deepfunc()
报错:
[Previous line repeated 996 more times]
3. 個人的な概要
再帰とは、関数が自分自身を呼び出す処理のことで、再帰が見つかったら戻る処理を考える必要がありますが、再帰の処理は最終値を見つけるか返すだけで、結果は出力されません。私たちの操作は主に再帰のプロセスによって返された値であり、それは深い谷でエコーを止めるようなものです。
2. 任意の数 n の階乗を求める練習をする
1. 一般的な方法
def func(n):
total = 1
for i in range(1,n+1):
total *= i
"""
total = total * i => 1 * 1
total = total * i => 1 * 1 * 2
total = total * i => 1 * 1 * 2 * 3
total = total * i => 1 * 1 * 2 * 3 * 4
total = total * i => 1 * 1 * 2 * 3 * 4 * 5
"""
return total
res = func(5)
print(res)
2. 再帰的方法
def func(n):
if n <= 1:
return 1
return n * func(n - 1)
res = func(5)
print(res)
# 代码解析:
# 去的过程
n = 5 return 5 * func(5 - 1) => 5*func(4)
n = 4 return 4 * func(4 - 1) => 4*func(3)
n = 3 return 3 * func(3 - 1) => 3*func(2)
n = 2 return 2 * func(2 - 1) => 2*func(1)
n = 1 return 1
# 回的过程
n = 2 return 2*func(1) => 2*1 [func(2)]
n = 3 return 3*func(2) => 3*2*1 [func(3)]
n = 4 return 4*func(3) => 4*3*2*1 [func(4)]
n = 5 return 5*func(4) => 5*4*3*2*1 [func(5)]
res = func(5) <=> 5*4*3*2*1 = 120
"""
# 通俗点
看着这个式子,n=5时,不满足<=1,跳到func(n-1)中,开始计算func(4),依旧不满足,直到n=1,才可以直接return 1;
到达终点后开始反弹,回到2,得出return 2 * 1,回到3,得出3 * func(2)也就是3*2*1,以此类推
3. 末尾再帰法
再帰とは層ごとに空間を開くことです。末尾再帰は特殊な再帰です。元の空間に直接開くのが特徴です。関数を何回呼び出しても、必要な空間は 1 つだけです。利点: space の最後の層の結果のみを考慮する必要があります
。リターン プロセスを考慮する必要はありません。
注: 末尾再帰ではパラメータ演算に値を入れる必要があります。
def jiecheng(n,endval=1):
if n <= 1:
return endval
return jiecheng(n-1, endval*n)
print(jiecheng(5))
# 代码解析:
# 去的过程
n = 5,endval = 1
return jiecheng(5-1,endval*n ) => return jiecheng(4,1*5)
n = 4,endval = 1*5
return jiecheng(4-1,endval*n ) => return jiecheng(3,1*5*4)
n = 3,endval = 1*5*4
return jiecheng(3-1,endval*n ) => return jiecheng(2,1*5*4*3)
n = 2,endval = 1*5*4*3
return jiecheng(2-1,endval*n ) => return jiecheng(1,1*5*4*3*2)
n = 1,endval = 1*5*4*3*2
if 1 <= 1 条件满足 return endval => return 1*5*4*3*2
# 回的过程
n = 2 return 1*5*4*3*2
n = 3 return 1*5*4*3*2
n = 4 return 1*5*4*3*2
n = 5 return 1*5*4*3*2
到此程序全部结束;
"""
为什么尾递归不需要考虑回的过程呢,因为函数目的是return endval,而endval的值已经在计算过程中出来了,即使返回上一层,程序会默认目的已达成,继续返回。
为什么要参数默认写死endval=1呢,因为阶乘就是1*2*。。。这种格式,我们需要给一个初始值,意味着这个1不是固定的,是根据实际情况来,写死也是为了用户只关注n的值即可
3. フィボナッチ数列の練習
1. 再帰的書き込み
def feb(n):
if n ==1 or n == 2:
return 1
# 当前值n = 上一个值(n-1) + 上上个值(n-2)
return feb(n-1) + feb(n-2)
res = feb(5)
print(res)
#代码解析:
斐波那契数列的定义是:第一个数为1,第二个数为1,从第三个数开始,每个数均为前两个数之和。
n = 5
return feb(4) + feb(3)
feb(3) + feb(2) + feb(3)
feb(2) + feb(1) + feb(2) + feb(3)
feb(2) + feb(1) + feb(2) + feb(2) + feb(1)
1+1+1+1+1=5
首先,我们将函数调用 feb(5) 传入参数5。
在函数内部,我们首先判断n的值是否等于1或2。由于5不等于1或2,所以我们将跳过这个条件语句。
接下来,我们将执行这行代码 return feb(n-1) + feb(n-2),由于n等于5,因
此时我们需要求出斐波那契数列的第5个数。根据斐波那契数列的定义,第5个数应该是前两个数之和,即第4个数和第3个数之和。
然后,我们需要计算 feb(4) 和 feb(3) 的值。首先,我们将调用 feb(4)。
在 feb(4) 函数内部,我们也需要计算斐波那契数列的第4个数,即第3个数和第2个数之和。因此,我们需要调用 feb(3) 和 feb(2) 来计算这个值。
在 feb(3) 函数内部,我们需要计算斐波那
那契数列的第3个数,即第2个数和第1个数之和。因此,我们需要调用 feb(2) 和 feb(1) 来计算这个值。
在 feb(2) 函数内部,由于 n 的值等于2,因此我们将直接返回1。
在 feb(1) 函数内部,由于 n 的值等于1,因此我们也将直接返回1。
现在,我们已经得到了 feb(2) 和 feb(1) 的值,因此我们可以计算 feb(3) 的值。根据斐波那契数列的定义,第3个数应该是前两个数之和,即1+1=2。因此,feb(3) 的返回值为2。
接下来,我们已经得到了 feb(3) 和 feb(2) 的值,因此我们可以计算 feb(4) 的值。根据斐波那契数列的定义,第4个数应该是前两个数之和,即2+1=3。因此,feb(4) 的返回值为3。
现在,我们已经得到了 feb(4) 和 feb(3) 的值,因此我们可以计算 feb(5) 的值。根据斐波那契数列的定义,第5个数应该是前两个数之和,即3+2=5。因此,feb(5) 的返回值为5。
最后,我们在主函数中将 feb(5) 的返回值打印出来,结果为5。
因此,这段代码的执行过程可以总结如下:
调用 feb(5) 函数来计算斐波那契数列的第5个数。
feb(5) 函数内部调用 feb(4) 和 feb(3) 函数来计算斐波那契数列的第4个数和第3个数。
feb(4) 函数内部调用 feb(3) 和 feb(2) 函数来计算斐波那契数列的第3个数和第2个数。
feb(3) 函数内部调用 feb(2) 和 feb(1) 函数来计算斐波那契数列的第2个数和第1个数。
feb(2) 函数内部直接返回值1。
feb(1) 函数内部直接返回值1。
feb(3) 函数内部得到 feb(2) 和 feb(1) 的返回值后,计算斐波那契数列的第3个数为2。
feb(4) 函数内部得到 feb(3) 和 feb(2) 的返回值后,计算斐波那契数列的第4个数为3。
feb(5) 函数内部得到 feb(4) 和 feb(3) 的返回值后,计算斐波那契数列的第5个数为5。
主函数将 feb(5) 的返回值打印出来,结果为5。