1. 利用遞歸函數求斐波那契值python版
首先我們要了解一下什麼是遞歸。
遞歸法,遞歸法就是利用上一個或者上幾個狀態來求取當前狀態的值(個人看法)。也可以說成函數自己調用自己的一種解決問題的策略。因此遞歸法通常是依託函數來實現的,遞歸函數總是會有一個出口,我們在解決遞歸問題時,只需要找出遞歸的關系式以及遞歸函數的出口(這兩個可以說是遞歸函數的核心了)。下面我將在這里舉求斐波那契值的例子帶領著大傢具體的實踐一下遞歸法。
很顯然遞歸函數的遞推式是:fib(n) = fib(n-1)+fib(n-2)。
遞歸函數的出口是當n為1時返回1,當n為0時返回0。
最後遞歸函數的核心代碼就可以寫出了:
然後總的代碼就是:
具體思路如下:
語句 return fib(n-1)+fib(n-2)的意思就是向前求斐波那契值,直到n-1=1,n-2=0
因為只有第1個和第0個斐波那契值是確定的
例:
當n=3時
第一次調用函數fib會執行第三條語句(因為n>1)這樣求回返回fib(2)+fib(1)
第二次調用函數時,因為2>1所有會返回fib(1)+fib(0);因為1不大於1,所以調用函數時
會執行第二條語句返回1值。
第三次調用函數,會執行第一和第二條語句,依次返回0和1從而求得fib(2)
fib(3)=fib(2)+fib(1)
fib(2)=fib(1)+fib(0)
即fib(3)=fib(1)+fib(0)+fib(1)=2*fib(1)+fib(0)
2. Python3:怎麼通過遞歸函數
函數的遞歸調用
遞歸問題是一個說簡單也簡單,說難也有點難理解的問題.我想非常有必要對其做一個總結.
首先理解一下遞歸的定義,遞歸就是直接或間接的調用自身.而至於什麼時候要用到遞歸,遞歸和非遞歸又有那些區別?又是一個不太容易掌握的問題,更難的是對於遞歸調用的理解.下面我們就從程序+圖形的角度對遞歸做一個全面的闡述.
我們從常見到的遞歸問題開始:
1 階層函數
#include <iostream>
using namespace std;
int factorial(int n)
{
if (n == 0)
{
return 1;
}
else
{
int result = factorial(n-1);
return n * result;
}
}
int main()
{
int x = factorial(3);
cout << x << endl;
return 0;
}
這是一個遞歸求階層函數的實現。很多朋友只是知道該這么實現的,也清楚它是通過不斷的遞歸調用求出的結果.但他們有些不清楚中間發生了些什麼.下面我們用圖對此做一個清楚的流程:
根據上面這個圖,大家可以很清楚的看出來這個函數的執行流程。我們的階層函數factorial被調用了4次.並且我們可以看出在調用後面的調用中,前面的調用並不退出。他們同時存在內存中。可見這是一件很浪費資源的事情。我們該次的參數是3.如果我們傳遞10000呢。那結果就可想而知了.肯定是溢出了.就用int型來接收結果別說10000,100就會產生溢出.即使不溢出我想那肯定也是見很浪費資源的事情.我們可以做一個粗略的估計:每次函數調用就單變數所需的內存為:兩個int型變數.n和result.在32位機器上佔8B.那麼10000就需要10001次函數調用.共需10001*8/1024 = 78KB.這只是變數所需的內存空間.其它的函數調用時函數入口地址等仍也需要佔用內存空間。可見遞歸調用產生了一個不小的開銷.
2 斐波那契數列
int Fib(int n)
{
if (n <= 1)
{
return n;
}
else
{
return Fib(n-1) + Fib(n-2);
}
}
這個函數遞歸與上面的那個有些不同.每次調用函數都會引起另外兩次的調用.最後將結果逐級返回.
我們可以看出這個遞歸函數同樣在調用後買的函數時,前面的不退出而是在等待後面的結果,最後求出總結果。這就是遞歸.
3
#include <iostream>
using namespace std;
void recursiveFunction1(int num)
{
if (num < 5)
{
cout << num << endl;
recursiveFunction1(num+1);
}
}
void recursiveFunction2(int num)
{
if (num < 5)
{
recursiveFunction2(num+1);
cout << num << endl;
}
}
int main()
{
recursiveFunction1(0);
recursiveFunction2(0);
return 0;
}
運行結果:
0
1
2
3
4
4
3
2
1
0
該程序中有兩個遞歸函數。傳遞同樣的參數,但他們的輸出結果剛好相反。理解這兩個函數的調用過程可以很好的幫助我們理解遞歸:
我想能夠把上面三個函數的遞歸調用過程理解了,你已經把遞歸調用理解的差不多了.並且從上面的遞歸調用中我們可以總結出遞歸的一個規律:他是逐級的調用,而在函數結束的時候是從最後面往前反序的結束.這種方式是很佔用資源,也很費時的。但是有的時候使用遞歸寫出來的程序很容易理解,很易讀.
為什麼使用遞歸:
1 有時候使用遞歸寫出來的程序很容易理解,很易讀.
2 有些問題只有遞歸能夠解決.非遞歸的方法無法實現.如:漢諾塔.
遞歸的條件:
並不是說所有的問題都可以使用遞歸解決,他必須的滿足一定的條件。即有一個出口點.也就是說當滿足一定條件時,程序可以結束,從而完成遞歸調用,否則就陷入了無限的遞歸調用之中了.並且這個條件還要是可達到的.
遞歸有哪些優點:
易讀,容易理解,代碼一般比較短.
遞歸有哪些缺點:
佔用內存資源多,費時,效率低下.
因此在我們寫程序的時候不要輕易的使用遞歸,雖然他有他的優點,但是我們要在易讀性和空間,效率上多做權衡.一般情況下我們還是使用非遞歸的方法解決問題.若一個演算法非遞歸解法非常難於理解。我們使用遞歸也未嘗不可.如:二叉樹的遍歷演算法.非遞歸的演算法很難與理解.而相比遞歸演算法就容易理解很多.
對於遞歸調用的問題,我們在前一段時間寫圖形學程序時,其中有一個四連同填充演算法就是使用遞歸的方法。結果當要填充的圖形稍微大一些時,程序就自動關閉了.這不是一個人的問題,所有人寫出來的都是這個問題.當時我們給與的解釋就是堆棧溢出。就多次遞歸調用佔用太多的內存資源致使堆棧溢出,程序沒有內存資源執行下去,從而被操作系統強制關閉了.這是一個真真切切的例子。所以我們在使用遞歸的時候需要權衡再三.
3. python 遞歸 實現 從前有座山
如果調用 flatten3([[1,2],3])的話
for sublist in nested:
for element in fatten(sublist):
yield element
sublist分別為[1,2]和3
遞歸調用 fattern([1,2])返回一個包含1,2的子生成器,for element in fatten返回1,2用yield語句將1,2放入父生成器中,有了yield父生成器中才會有子生成器中的值
遞歸調用 flatten(3) TypeError執行yield 3,返回一個包含3的子生成器,yield element,3才會包含在父生成中
4. python利用遞歸方法求5!
def fact(a):
#a的階乘
if a == 1:
return 1#如果a=1(最後一個數),那麼就返回1(還要乘以前面)
return a * fact(a - 1)#a! = a * (a-1)!
print(fact(5))#輸出5的階乘
輸出效果:120
5. python遞歸演算法經典實例有哪些
程序調用自身的編程技巧稱為遞歸( recursion)。遞歸做為一種演算法在程序設計語言中廣泛應用。 一個過程或函數在其定義或說明中有直接或間接調用自身的一種方法。
它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計算,大大地減少了程序的代碼量。
遞歸的能力在於用有限的語句來定義對象的無限集合。一般來說,遞歸需要有邊界條件、遞歸前進段和遞歸返回段。當邊界條件不滿足時,遞歸前進;當邊界條件滿足時,遞歸返回。
Python
是完全面向對象的語言。函數、模塊、數字、字元串都是對象。並且完全支持繼承、重載、派生、多繼承,有益於增強源代碼的復用性。Python支持重載運算符和動態類型。相對於Lisp這種傳統的函數式編程語言,Python對函數式設計只提供了有限的支持。有兩個標准庫(functools, itertools)提供了Haskell和Standard ML中久經考驗的函數式程序設計工具。
6. python 遞歸函數中return的用法
return之前要執行的。
給你舉個簡單例子
1
2
def add(a, b):
return a + b
這個例子很簡單,但是說明了函數return之前要執行a+b這個操作
a+b也可以當做一個函數
在復雜一點
1
2
3
4
5
def multi(a, b):
return a * b
def add(a, b):
return a + multi(a, b)
同樣這里在add函數中, 執行return之前,要先把a+mulit(a,b )在返回
如果這就是你迷惑的地方,那就選我把- -~
7. python中輸入一個整數,返回一個列表,將數字用逗號隔開 用遞歸完成
按照你的要求,編寫的Python遞歸程序如下
deffunc(l,n):
ifn==0:
returnl;
else:
l.insert(0,n%10)
returnfunc(l,n//10)
n=int(input())
l=[]
print(func(l,n))
源代碼如下(注意源代碼的縮進)
8. Python 遞歸函數基例
所謂基例就是不需要遞歸就能求解的,一般來說是問題的最小規模下的解。
例如:斐波那契數列遞歸,f(n) = f(n-1) + f(n-2),基例是1和2,f(1)和f(2)結果都是1
再比如:漢諾塔遞歸,基例就是1個盤子的情況,只需移動一次,無需遞歸
遞歸必須有基例,否則就是無法退出的遞歸,不能求解。
9. python 遞歸實現組合
用迭代器比較好
def combin(items, n=None):
if n is None:
n = len(items)
for i in range(len(items)):
v = items[i:i+1]
if n == 1:
yield v
else:
rest = items[i+1:]
for c in combin(rest, n-1):
yield v + c
for i in range(len([1,2,3,4])):
for j in combin([1,2,3,4], i+1):
print j,
10. Python 遞歸函數基例
所謂基例就是不需要遞歸就能求解的,一般來說是問題的最小規模下的解。
例如:斐波那契數列遞歸,f(n)
=
f(n-1)
+
f(n-2),基例是1和2,f(1)和f(2)結果都是1
再比如:漢諾塔遞歸,基例就是1個盤子的情況,只需移動一次,無需遞歸
遞歸必須有基例,否則就是無法退出的遞歸,不能求解。