iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 21
0

遞迴的意義

OOP基本用法是不會碰到遞迴的,但在複雜OOP世界裡 大部分都發生在回傳函式與多重繼承裡面。
遞迴,執行上表面跟迴圈沒差別。但迴圈較為直觀 不容易自己造成,而遞迴則是會不小心在調用時發生 舉個栗子:
產生了死結般的無限遞迴

class mostly:
    name="boss1"
    def www(self):
        print("我是boss1")
class sm(mostly):
    name="user1"
    def www(self):
        print("boss1小弟")          
def Show(mostly):
    mostly.www()
    Show(sm())
Show(sm()) #繼承物件裡已有同個方法 不能同時存在

Show(sm()) 相當於同時呼叫兩個同方法物件,這會促使編輯器同時遞迴同方法(進而產生無限遞迴)。
像昨天學習到MRO(方法解析順序),和super()。就不能同時遞迴
因為在OOP的世界,物件都是獨一無二的。同時有一模一樣的方法,就會因為要呼叫到而無止境的遞迴。


有需要遞迴的時候?

如果遞迴只有缺點,那就不是那麼重要了。

  • 迴圈並不是解決複雜資料的方法,而遞迴為何為在處理複雜資料時是好朋友呢?因為遞迴可用函式本身的對應數來做方法上的呼叫。這樣比較有數學的邏輯
    遞迴最大特色就是呼叫自身方法與屬性
  • 遞迴的運作模式跟迴圈差在:
    迴圈是大範圍同時執行(跑),而事先就給了範圍
    但遞迴把要做的方法分成一個個小部分,而沒給範圍。而是給個參考值,讓自身依循演算法執行。
    (所以會發現越趨複雜的程式(ex:神經網路) 一定會用到)

Ex:(99乘法表迴圈)

#迴圈
for i in range(1,9):
    i +=1
    if i+1:
        print("\n")
    for j in range(0,9):
        j+=1
        print("%dx%d=" %(i,j) ,i*j, end=" , ")

簡單的99乘法使用迴圈比較簡單

  • 河內塔
    此為遞迴最經典的題目。
    執行方式:一個套環從下到上由大到小排好(不考慮雙色)。現在有n跟柱子,要將全部套環移到指定柱子上,且一次只能移動一個套環。

這時用迴圈就沒辦法了,反而用遞迴較簡單

def hanoi(n,a,b,c):
	if n == 1:
		print(a, "-->" , c)
	else:
		hanoi(n-1 , a , c , b)
		hanoi(1 , a , b , c)
		hanoi(n-1 , b , a , c) #遞迴不加return
hanoi(5,'A','B','C') #五環三柱

總結:

迴圈處理簡單資料,較直觀
遞迴主要處理複雜資料,較不直觀

遞迴深度

當遞迴呼叫自身物件時,會有一個呼叫限制。

import sys
sys.getrecursionlimit()

得到此編輯器Rmax(遞迴最大值),但不用擔心。只要超過Rmax的話就給他指定新值就好了

import sys
sys.setrecursionlimit(100000000)

上一篇
[D20] python變數作用域
下一篇
[D22] 剖面導向與裝飾器
系列文
從寫程式到脫離菜雞的歷練(以python為主的資處與檔案權限)32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言