亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

Python | 遞歸

qieangel2013 / 3118人閱讀

摘要:那假如我們用遞歸來(lái)描述這種情況呢定義基本情況其它情形所以在上述求和中的定義又用到了自己本身的定義,這就構(gòu)成了遞歸。

說(shuō)起遞歸,我覺(jué)得其實(shí)大部分人應(yīng)該是不陌生的,遞歸廣泛存在于生活中。
比如:

The woman in this image holds an object that contains a smaller image of her holding an identical object, which in turn contains a smaller image of herself holding an identical object, and so forth.[from wikipedia]

那么遞歸的定義是什么呢?
在數(shù)學(xué)和計(jì)算機(jī)科學(xué)中,我們給出一個(gè)比較傳統(tǒng)的定義是:
它們有兩個(gè)特性。

一個(gè)基本特例,也稱(chēng)作平凡(一般)情況,它是遞歸終止的情形

一個(gè)已定義好的規(guī)則來(lái)使其它非基本的情形轉(zhuǎn)化為基本情形

可能這個(gè)上面的定義比較枯燥,那么我們用一個(gè)經(jīng)典的例子來(lái)說(shuō)明一下。

Fibonacci sequence

Fib(0) = 0, 是一個(gè)基本情況
Fib(o) = 1, 是第二個(gè)基本情況
所以 Fibonacci sequence 總共有兩個(gè)基本情形
對(duì)于其它情形,我們定義 Fib(n) = Fib(n-1) + Fib(n-2)

到這里,估計(jì)讀者已經(jīng)對(duì)遞歸有一個(gè)大概的印象了,那么在Python中我們?cè)趺从眠f歸來(lái)實(shí)現(xiàn)某些特定的功能呢?

我首先用一些簡(jiǎn)單的例子來(lái)進(jìn)行說(shuō)明。

例1.

假如你要求序列數(shù)列 1, 2, 3, 4, ..., n 的和。比如對(duì)于n=4, 其和是10。那假如我們用遞歸來(lái)描述這種情況呢?
定義:

基本情況:S(1) = 1

其它情形: S(n) = S(n-1) + n
所以在上述求和中S(n)的定義又用到了自己本身的定義,這就構(gòu)成了遞歸。

我們用Python來(lái)實(shí)現(xiàn)以下上面的思路。

def Sum(n):
    if n==1:
    #對(duì)應(yīng)基本情形
        return 1
    return Sum(n-1) + n#對(duì)應(yīng)遞歸情形

>>> Sum(4)
10
>>> Sum(10)
55
>>> Sum(100)
5050

代碼如上,可以看到,問(wèn)題如果用遞歸來(lái)解決的話,可以與現(xiàn)實(shí)很好的結(jié)合,因?yàn)楝F(xiàn)實(shí)中有很多問(wèn)題也是遞歸定義的。
此外,使用遞歸編程也比較簡(jiǎn)單。

例2.
經(jīng)典的求階乘

定義 F(n) 為階乘函數(shù)。

基本情形: F(0) = 1, F(1) = 1

其它情形: F(n) = F(n-1) * n

實(shí)現(xiàn):

def F(n):
    if n==0 or n==1:
    #對(duì)應(yīng)基本情形
        return 1
    return F(n-1)*n#對(duì)應(yīng)遞歸情形

>>> F(4)
24
>>> F(10)
3628800
例3.

斐波那契數(shù)列

定義Fib(n) 為斐波那契數(shù)列

基本情形:

Fib(0) = 1, Fib(1) = 1

其它情形:

Fib(n) = Fib(n-1)+Fib(n-2)

實(shí)現(xiàn):

def Fib(n):
    if n==0 or n==1:
        return 1
    return Fib(n-1)+Fib(n-2)

>>> Fib(10)
89
>>> Fib(8)
34
>>> 

除此以外,接下來(lái)的幾道題也可以用遞歸求解,雖然可能在有些問(wèn)題上,遞歸并不是最合適的工具,可以使用迭代得到比遞歸更為高效的算法。

例4.

計(jì)算s=a+aa+aaa+aaaa+aa...a,其中 a是一個(gè)數(shù)字。
其中,a 以及 n 由用戶(hù)輸入,但是我們?cè)谶@里就直接給定了。

定義:
函數(shù) SSS(a, n) 的值為上述所求值

基本情形:

SSS(a, 1) = a

其它情形:
SSS(a, n) = SSS(a, n-1) + a...a(共n項(xiàng))

def SSS(a, n):

    #這里我說(shuō)明一下,直接用input函數(shù)得到的就是字符串,除非你已經(jīng)做了轉(zhuǎn)換
    #所以,我們?cè)O(shè)定a、n都是字符串
    n = int(n)#轉(zhuǎn)換
    if n == 1:
        return int(a)
    return SSS(a, n-1) + int(a * n)#請(qǐng)思考這里a*n

>>> SSS("2", "5")
24690
>>> SSS("2", "1")
2
>>> SSS("2", "2")
24
>>> 
例5.

在一個(gè)排列中,如果一對(duì)數(shù)的前后位置與大小順序相反,即前面的數(shù)大于后面的數(shù),那么它們就稱(chēng)為一個(gè)逆序。一個(gè)排列中逆序的總數(shù)就稱(chēng)為這個(gè)排列的逆序數(shù)。比如排列[1,4,3,2]中,4在3前面,但4>3,則4和3逆序,同理,4和2逆序,3和2逆序,共有3對(duì)逆序,因此這組排列的逆序數(shù)為3?,F(xiàn)在請(qǐng)你設(shè)計(jì)一個(gè)程序,判斷用戶(hù)輸入的數(shù)組的逆序數(shù)。

定義:
OP(seq, n)為序列seq中前n項(xiàng)的逆序數(shù)

基本情形:
OP(seq[1...n], 1) = 0,對(duì)于只有一個(gè)元素的集合,逆序數(shù)必然只有0

其它情形:
OP(seq[1...n], n) = OP(seq[1...n, n-1] + F(n),其中,F(xiàn)(n)是n關(guān)于seq[1...n-1]的逆序數(shù).

實(shí)現(xiàn):

def OP(seq, n):
    if n == 1:
        return 0
    #不為0
    Fn = 0
    for i in range(0, n-1):
        if seq[n-1] < seq[i]:
            Fn+=1
    return OP(seq, n-1)+Fn

>>> s = [5, 4, 3, 2, 1]
>>> s
[5, 4, 3, 2, 1]
>>> OP(s, len(s))
10
>>> 
例6.

輸入某年某月某日,判斷這一天是這一年的第幾天?

假如我們要用遞歸實(shí)現(xiàn)這樣的程序,該怎么考慮呢?

首先,我們得定義出我們的遞歸函數(shù),它有三個(gè)變量,年,月,日。

定義:WhichDay(year, month, day)

基本情況: WhichDay(year, month, day) 當(dāng)month = 1時(shí),可以看出,此時(shí)該函數(shù)的值為 day

其它情形:
WhichDay(year, month, day) = WhichDay(year, month-1, F(month-1))+day

請(qǐng)注意,我在遞歸式子中使用的F(month-1), 這個(gè)代表(month-1)這一月的總天數(shù)。

實(shí)現(xiàn):

F = { 1:31, 2: 28, 3:31, 4:30, 5:31, 6:30, 7:31, 8:31, 9:30, 10: 31, 11: 30, 12: 31}
def WhichDay(year, month, day):
    if month == 1:
        return day
    flag = 0#二月是否閏年標(biāo)志
    if month == 3:
        #二月特殊處理
        #這里month等于3請(qǐng)讀者思考
        if (year % 4 == 0 and year % 100!=0) or year % 400 == 0:
            flag = 1#判斷閏年
    return WhichDay(year, month-1, F[month-1]+flag)+day

>>> WhichDay(2016, 2, 1)
32
>>> WhichDay(2016, 11, 8)
313
>>> WhichDay(2016, 12, 31)
366
>>> 

雖然上面的問(wèn)題并不是很適合使用遞歸來(lái)實(shí)現(xiàn),但是我主要是想跟大家分享一個(gè)遞歸解決問(wèn)題中的思路,以及遞歸是一個(gè)很強(qiáng)大的工具,但是同時(shí)會(huì)產(chǎn)生很?chē)?yán)重的效率問(wèn)題。關(guān)于這一點(diǎn),可以查看遞歸優(yōu)化,可以很大程度上改善遞歸的效率。

希望讀者看完這篇教程,可以有所收獲,謝謝。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/44235.html

相關(guān)文章

  • 處理python遞歸函數(shù)及遞歸算法頻次受限制難題

      本文關(guān)鍵闡述了處理python遞歸函數(shù)及遞歸算法頻次受限制難題,具有非常好的實(shí)用價(jià)值,希望能幫助到大家。如有誤或者未考慮到真正的地區(qū),望鼎力相助  遞歸函數(shù)及遞歸算法頻次受限制  一個(gè)函數(shù)在外部啟用自身,那么這樣的函數(shù)是遞歸函數(shù)。遞歸算法要反復(fù)應(yīng)用自身,每遞歸算法一回,越近最后的值。如果一個(gè)難題需要由很多類(lèi)似小問(wèn)題處理,可以選擇應(yīng)用遞歸函數(shù)。伴隨著遞歸算法的深層次,難題經(jīng)營(yíng)規(guī)模對(duì)比之前都應(yīng)該所...

    89542767 評(píng)論0 收藏0
  • Python開(kāi)啟尾遞歸優(yōu)化!

    摘要:尾遞歸優(yōu)化一般遞歸與尾遞歸一般遞歸執(zhí)行可以看到一般遞歸每一級(jí)遞歸都產(chǎn)生了新的局部變量必須創(chuàng)建新的調(diào)用棧隨著遞歸深度的增加創(chuàng)建的棧越來(lái)越多造成爆棧尾遞歸尾遞歸基于函數(shù)的尾調(diào)用每一級(jí)調(diào)用直接返回遞歸函數(shù)更新調(diào)用棧沒(méi)有新局部變量的產(chǎn)生類(lèi)似迭代的 Python尾遞歸優(yōu)化 一般遞歸與尾遞歸 一般遞歸: def normal_recursion(n): if n == 1: ...

    junnplus 評(píng)論0 收藏0
  • 小李飛刀:python你慢點(diǎn)飛,我的腦子還在后面追

    摘要:默認(rèn)參數(shù)設(shè)置默認(rèn)參數(shù)時(shí),有幾點(diǎn)要注意一是必選參數(shù)在前,默認(rèn)參數(shù)在后,否則的解釋器會(huì)報(bào)錯(cuò)二是如何設(shè)置默認(rèn)參數(shù)。注意此處,獲得的其實(shí)是的拷貝,函數(shù)內(nèi)對(duì)的改變不會(huì)影響到。使用遞歸函數(shù)需要注意防止棧溢出。 總是在最前面的叨逼叨 最近總是在想成長(zhǎng)這兩個(gè)很常常被提起的事情,這對(duì)于一個(gè)已經(jīng)25歲的半中年而言,已經(jīng)是一個(gè)不太能高頻提起的詞。但是,最近一些事情吧,總讓我覺(jué)得我的生長(zhǎng)期似乎比正常人來(lái)的晚了...

    kevin 評(píng)論0 收藏0
  • Python筆記

    摘要:針對(duì)尾遞歸優(yōu)化的語(yǔ)言可以通過(guò)尾遞歸防止棧溢出。尾遞歸事實(shí)上和循環(huán)是等價(jià)的,沒(méi)有循環(huán)語(yǔ)句的編程語(yǔ)言只能通過(guò)尾遞歸實(shí)現(xiàn)循環(huán)。標(biāo)準(zhǔn)的解釋器沒(méi)有針對(duì)尾遞歸做優(yōu)化,任何遞歸函數(shù)都存在棧溢出的問(wèn)題。 python 頭部: #!/usr/bin/env python # -*- coding: utf-8 -*- 函數(shù)的參數(shù) Python的函數(shù)具有非常靈活的參數(shù)形態(tài),既可以實(shí)現(xiàn)簡(jiǎn)單的調(diào)用,又可以傳入...

    yuxue 評(píng)論0 收藏0
  • 【數(shù)據(jù)科學(xué)系統(tǒng)學(xué)習(xí)】Python # 編程基礎(chǔ)[一]

    摘要:在定義函數(shù)時(shí)給定的名稱(chēng)稱(chēng)作形參,在調(diào)用函數(shù)時(shí)你所提供給函數(shù)的值稱(chēng)作實(shí)參。調(diào)用函數(shù)要調(diào)用一個(gè)函數(shù),需要知道函數(shù)的名稱(chēng)和參數(shù)。默認(rèn)參數(shù)值可以有效幫助解決這一情況。是默認(rèn)參數(shù)定義默認(rèn)參數(shù)要牢記一點(diǎn)默認(rèn)參數(shù)必須指向不變對(duì)象。 關(guān)于數(shù)據(jù)科學(xué)在做什么,我們已經(jīng)在前兩篇文章中進(jìn)行了總結(jié),即專(zhuān)題概述和描述性統(tǒng)計(jì)分析。要進(jìn)行數(shù)據(jù)科學(xué)的探索,需要一個(gè)好工具,就是Python。從本篇開(kāi)始,將總結(jié)學(xué)習(xí)Pyth...

    luckyyulin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<