以前有接觸過遞歸,看到別人寫的遞歸函數的代碼,好生羨慕,怎麼就能寫這麼好呢?我怎麼就想不到這樣寫呢?如此等等。python
就拿fibonacci函數來講吧,一個普通的函數可能這樣寫:算法
def fib(n): if n == 0: return 0 elif n == 1: return 1 else: return fib(n-1) + fib(n-2)
我看到這個函數的思考方式是這樣的:app
1. 當n=0時:返回0 2. 當n=1時:返回1 3. 當n=2時: 1. 首先去調用n=1,返回1 2. 再去調用n=0,返回0 3. 把0和1相加返回1 4. 當n=3時: 1. 調用n=2 1. 調用n=1,返回1 2. 調用n=0,返回0 3. 相加返回1 2. 調用n=1,返回1 3. 把1和1相加返回2 5. 等等
想到這我頭都要爆了,完全被人家的函數折服了,看來我是寫不成這麼好的函數了。函數
但我轉念一想,這個函數的本質是fibnacci序列,我何不迴歸fibonacci自己呢?fibonacci用數學公式表示應該是這樣:spa
看到公式我恍然大悟,上面那個函數不就是根據這個公式直接翻譯的嘛!原來我一直思考都是順着函數的代碼思考,這樣確定會以爲很難,
正確的思考方式應該是從算法出發而後再寫代碼。翻譯
通過了上面的慘痛教訓看看我能不能寫出正確的fibonacci序列函數,分段函數的公式應該是這樣的:code
那麼直接寫成代碼就應該是這樣的:orm
def fib_seq(n): seq = [] if n == 0: seq.append(0) else: seq.extend(fib_seq(n-1)) seq.append(fib(n)) return seq
咦,這兩個append好像能夠合併:遞歸
def fib_seq(n): seq = [] if n > 0: seq.extend(fib_seq(n-1)) seq.append(fib(n)) return seq
哇,原來如此!ip