亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

了解遞歸函數是如何工作的

了解遞歸函數是如何工作的

了解遞歸函數是如何工作的正如標題所解釋的那樣,我有一個非?;镜木幊虇栴},只是我還不能摸索。過濾掉所有的(非常聰明的)“為了理解遞歸,你必須首先理解遞歸。來自各種在線帖子的回復,我仍然不太明白。當我們面對不知道我們不知道的事情時,我們會傾向于提出錯誤的問題或不正確地提出正確的問題-我會分享我的“想法”,我的問題是希望有類似觀點的人能夠分享一些知識,幫助我打開遞歸燈泡!下面是函數(語法用SWIFT編寫):func sumInts(a: Int, b: Int) -> Int {     if (a > b) {         return 0     } else {         return a + sumInts(a: a + 1, b: b)     } }我們將使用2和5作為我們的論點:println(sumInts(a: 2, b: 5))顯然答案是14,但我不清楚這個價值是如何實現的。這是我的兩個大雜燴:函數被遞歸調用,直到滿足條件為止。該條件為a>b。當滿足此條件時,返回0。乍一看,我希望返回值為0,這顯然是不正確的。在每次迭代中打印出‘a’值將產生一個我所期望的值:2、3、4、5(在這里,5+1>b滿足第一個條件:a>b),但我仍然不知道如何實現14的值。我的第一個想法是,類似的事情正在神奇地發生:var answer = a; answer += a+1 until a > b; return answer;所以排除魔法,我就是得不到什么。我很想知道發生了什么,而不僅僅是含蓄的。如果有人能很好地解釋這種函數在技術上發生了什么,為什么結果不是0,以及最終結果是怎樣的,a + sumInts(a: a + 1, b: b) = 14我會永遠欠你的。
查看完整描述

3 回答

?
千萬里不及你

TA貢獻1784條經驗 獲得超9個贊

 這種混淆是因為把它看作是被多次調用的“相同功能”。如果您認為它是“被調用的同一個函數的許多副本”,那么它可能會更清楚:

只有一個函數的副本返回0,而且它不是第一個(這是最后一個)。所以第一個調用的結果不是0。

至于第二個混亂的地方,我認為用英語拼寫遞歸會更容易一些。讀這一行:

return a + sumInts(a + 1, b: b)

作為“返回‘a’+的值(函數的另一個副本的返回值,即‘a’+的副本的值(函數的另一個副本的返回值,它是‘a’+(.)的第二個副本的值”),函數的每一個副本都會產生一個自身的新副本,a增加1,直到滿足a>b條件。

當您到達a>b條件為true時,您有一個(可能任意地)長的函數副本堆棧,所有這些副本都在運行的中間,它們都在等待下一個副本的結果,以找出它們應該添加到‘a’中的內容。

(編輯:另外,需要注意的是,我提到的函數的副本堆棧是一個真正的東西,占用了真正的內存,如果程序太大,就會崩潰。編譯器在某些情況下可以優化它,但是在許多語言中,耗盡堆??臻g是遞歸函數的一個重要而不幸的限制)


查看完整回答
反對 回復 2019-07-04
?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

1.函數被遞歸調用,直到滿足條件。那個條件是a > b..當滿足此條件時,返回0。乍一看,我希望返回值為0,這顯然是不正確的。

以下是計算機計算sumInts(2,5)如果它能夠:

I want to compute sumInts(2, 5)
for this, I need to compute sumInts(3, 5)
and add 2 to the result.
  I want to compute sumInts(3, 5)
  for this, I need to compute sumInts(4, 5)
  and add 3 to the result.
    I want to compute sumInts(4, 5)
    for this, I need to compute sumInts(5, 5)
    and add 4 to the result.
      I want to compute sumInts(5, 5)
      for this, I need to compute sumInts(6, 5)
      and add 5 to the result.
        I want to compute sumInts(6, 5)
        since 6 > 5, this is zero.
      The computation yielded 0, therefore I shall return 5 = 5 + 0.
    The computation yielded 5, therefore I shall return 9 = 4 + 5.
  The computation yielded 9, therefore I shall return 12 = 3 + 9.
The computation yielded 12, therefore I shall return 14 = 2 + 12.

如您所見,對函數的調用sumInts實際上返回0,但這不是最后的值,因為計算機仍然必須將5加到0,然后4到結果,然后3,然后2,正如我們計算機的最后四句話所描述的。注意,在遞歸中,計算機不僅必須計算遞歸調用,還必須記住如何處理遞歸調用返回的值。計算機內存中有一個特殊的區域叫做堆棧在保存此類信息的地方,這個空間是有限的,過于遞歸的函數可以耗盡堆棧:這是堆棧溢出給我們最愛的網站命名。

你的聲明似乎是隱含的假設,即計算機在執行遞歸調用時忘記了它所處的位置,但它沒有,這就是為什么您的結論與您的觀察結果不一致的原因。

2.在每次迭代中輸出‘a’值將產生一個我所期望的值:2、3、4、5(在這里,5+1>b滿足第一個條件:a>b),但我仍然不知道如何實現14的值。

這是因為返回值不是a的價值之和a和遞歸調用返回的值。


查看完整回答
反對 回復 2019-07-04
?
偶然的你

TA貢獻1841條經驗 獲得超3個贊

要理解遞歸,您必須以不同的方式考慮這個問題。與其從整體上講有意義的大量邏輯步驟,不如把一個大問題分解成較小的問題,然后解決這些問題,一旦你有了子問題的答案,你就把子問題的結果結合起來,從而解決更大的問題。想想你和你的朋友們,他們需要數一下大桶里彈珠的數量。你做每一件事,拿一個小桶,然后逐個數,當你做完后,你把總數加在一起。好吧,如果你們每個人都找到了一些朋友,然后再把桶分開,那么你只需要等待這些其他的朋友計算出他們的總數,把它拿回給你們每個人,然后把它們加起來。諸若此類。特例是,當你只有一個大理石數,然后你只是返回它,并說1。讓其他人做你上面的加法你完成了。

您必須記住,每當函數遞歸地調用自己時,它就會創建一個包含問題子集的新上下文,一旦該部分得到解決,它就會被返回,以便上一次迭代能夠完成。

讓我帶你看看這些步驟:

sumInts(a: 2, b: 5) will return: 2 + sumInts(a: 3, b: 5)
sumInts(a: 3, b: 5) will return: 3 + sumInts(a: 4, b: 5)
sumInts(a: 4, b: 5) will return: 4 + sumInts(a: 5, b: 5)
sumInts(a: 5, b: 5) will return: 5 + sumInts(a: 6, b: 5)
sumInts(a: 6, b: 5) will return: 0

一旦執行了求和(a:6,b:5),就可以計算結果,因此可以使用所獲得的結果回滾:

 sumInts(a: 6, b: 5) = 0
 sumInts(a: 5, b: 5) = 5 + 0 = 5
 sumInts(a: 4, b: 5) = 4 + 5 = 9
 sumInts(a: 3, b: 5) = 3 + 9 = 12
 sumInts(a: 2, b: 5) = 2 + 12 = 14.

另一種表示遞歸結構的方法:

 sumInts(a: 2, b: 5) = 2 + sumInts(a: 3, b: 5)
 sumInts(a: 2, b: 5) = 2 + 3 + sumInts(a: 4, b: 5)  
 sumInts(a: 2, b: 5) = 2 + 3 + 4 + sumInts(a: 5, b: 5)  
 sumInts(a: 2, b: 5) = 2 + 3 + 4 + 5 + sumInts(a: 6, b: 5)
 sumInts(a: 2, b: 5) = 2 + 3 + 4 + 5 + 0
 sumInts(a: 2, b: 5) = 14


查看完整回答
反對 回復 2019-07-04
  • 3 回答
  • 0 關注
  • 506 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號