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

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

需要遞歸方面的幫助

需要遞歸方面的幫助

一只甜甜圈 2023-10-05 16:31:45
我正在嘗試使用遞歸計算數組中 5 個數字的總和。但是,我從遞歸函數得到的輸出為 0。如果我取消注釋 print 語句,我得到的總和為 15,但該函數返回的總和為 0。我在這里做錯了什么?我的代碼-def calcsum(arr):  i = 0  sum = 0  solution(arr,sum,i)  return sumdef solution(arr,sum,i):  if i == len(arr):    return  sum = sum + arr[i]  #print(sum,i)  solution(arr,sum,i+1)print(calcsum([1,2,3,4,5]))
查看完整描述

4 回答

?
30秒到達戰場

TA貢獻1828條經驗 獲得超6個贊

您的代碼至少存在五個問題:

  • solution(arr, sum, i)對in的調用calcsum不會修改calcsum局部變量sum,因此calcsum始終返回 0;

  • 您在 中 中編寫了return而不是return sum在最終情況下進行遞歸solution,因此在這種情況下solution將返回None而不是返回總和

  • 您將遞歸調用編寫為solution(arr,sum,i+1)而不是return solution(arr,sum,i+1)or some_variable = solution(arr,sum,i+1),因此無論如何都會忽略遞歸調用的返回值;return除了塊內的語句之外,沒有任何語句if,因此該函數solution不會有返回值(或者更準確地說,它將返回None);

  • 您似乎相信修改sum內部solution會修改sum整個程序中調用的任何變量。這是錯誤的。sum是函數的局部變量,修改它對程序的其余部分沒有影響。

  • 在 python 中調用變量sum是一個壞主意;這是內置函數的名稱,因此您應該嘗試為變量找到另一個名稱。

為了說明第四點,請嘗試以下代碼:

def mostly_harmless(n):

  n = 7


n = 8

mostly_harmless(n)

print('Does this set n to 7? Am I about to print 8 or 7?')

print(n)


print()


mostly_harmless(12)

print('did we set 12 = 7? did we just break all of mathematics?')

print('making sure 12 is still 12:')

print(12)

print('making sure n is still n:')

print(n)

考慮到這一點,我們可以修復您的代碼:


def calcsum(arr):

  return solution(arr, 0, 0)


def solution(arr, sum, i):

  if i == len(arr):

    return sum

  else:

    return solution(arr, sum + arr[i], i+1)


print(calcsum([1,2,3,4,5]))

實際上,我們可以使用默認參數進一步簡化代碼:


def calcsum(arr, sum=0, i=0):

  if i == len(arr):

    return sum

  else:

    return calcsum(arr, sum + arr[i], i+1)


print(calcsum([1,2,3,4,5]))

但請注意,python并不是一門喜歡遞歸的語言。在其他一些編程語言中,遞歸非常好,并且與 for 循環和 while 循環一樣高效。但在 python 中卻并非如此。在Python中,遞歸比循環慢得多,并且使用更多的內存。我們可以用 for 循環重寫你的程序:


def calcsum(arr):

  sum = 0

  for i in range(len(arr)):

    sum += arr[i]

  return sum


print(calcsum([1,2,3,4,5]))

或者甚至更好:


def calcsum(arr):

  sum = 0

  for v in arr:

    sum += v

  return sum


print(calcsum([1,2,3,4,5]))

另請注意,在 python 中調用變量sum是一個壞主意,因為sum是 python 中內置函數的名稱。您可以在python 文檔中找到內置函數列表;嘗試為您的變量指定其他名稱。


毫不奇怪,該函數sum自行計算總和:


print(sum([1,2,3,4,5]))

那么為什么調用變量這么糟糕呢sum?好吧,那么我們就失去了對同名內置函數的訪問:


sum = 7

print(sum([1,2,3,4,5]))

# Traceback (most recent call last):

#   File "<stdin>", line 1, in <module>

# TypeError: 'int' object is not callable

通常sum指內置函數;但現在它引用一個等于7;的變量 當我嘗試調用 時sum([1,2,3,4,5]),就好像我嘗試調用一樣7([1,2,3,4,5]),這是沒有意義的,因為它7不是一個函數。


查看完整回答
反對 回復 2023-10-05
?
慕勒3428872

TA貢獻1848條經驗 獲得超6個贊

您可以使其按您的方式工作,即增加sum中的變量calcsum,如果您將solution其放入其中并增加外部sum而不是擁有自己的變量。arr那么也無需通過。


def calcsum(arr):


  def solution(i):

    nonlocal sum

    if i == len(arr):

      return


    sum = sum + arr[i]

    solution(i+1)


  sum = 0

  solution(0)

  return sum


print(calcsum([1,2,3,4,5]))


查看完整回答
反對 回復 2023-10-05
?
嗶嗶one

TA貢獻1854條經驗 獲得超8個贊

正如已經提到的,您應該返回總和。這是一個迭代器版本:


def calcsum(arr):

    return solution(iter(arr), 0)


def solution(it, sum):

    for x in it:

        return solution(it, sum + x)

    return sum


print(calcsum([1,2,3,4,5]))

僅使用一個函數和一個參數的更短方法,在遞歸x 后添加:


def calcsum(it):

    it = iter(it)

    for x in it:

        return x + calcsum(it)

    return 0


print(calcsum([1,2,3,4,5]))

兩種解決方案都需要線性時間,而類似的解決方案只需要arr并將其分成arr[0]和arr[1:],而后者需要整體二次時間。通過對 1000 個值的列表求和來比較此迭代器版本與該列表版本的一個小基準測試:


0.28 ms  calcsum_1

2.70 ms  calcsum_2

基準代碼:


from timeit import repeat


def calcsum_1(it):

    it = iter(it)

    for x in it:

        return x + calcsum_1(it)

    return 0


def calcsum_2(arr):

    if arr:

        x, rest = arr[0], arr[1:]

        return x + calcsum_2(rest)

    return 0


arr = [1] * 1000


for _ in range(3):

    for f in calcsum_1, calcsum_2:

        t = min(repeat(lambda: f(arr), number=1000))

        print('%.2f ms ' % t, f.__name__)

    print()


查看完整回答
反對 回復 2023-10-05
?
嚕嚕噠

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

請記住,遞歸至少有兩種情況:

  • 基本情況:返回合計值

  • 遞歸情況:返回遞歸結果

這兩種情況都不會返回值!試試這個:


def solution(arr, sum_, i):

    if i == len(arr):

        return sum_


    sum_ += arr[i]

    return solution(arr, sum_, i+1)

此外,僅僅調用solution不會改變sumin的值calcsum,因此return sum總是給出0. 嘗試改為:


def calcsum(arr):

    return solution(arr, 0, 0)

(順便說一句,這種創建函數的結構,將調用委托給帶有一些附加參數的助手,這讓我想起了很多 Haskell,你可以在其中編寫:


calcsum :: Num a => [a] -> a

calcsum = go 0 0

  where go :: Num a => Int -> Int -> [a] -> a

        go acc idx xs

            | length xs >= idx = acc

            | otherwise        = go (acc + (xs !! idx)) idx+1 xs

另外你的邏輯有點復雜??紤]一下類似的事情:


def solution(arr):

    if arr:

        # Recursive case

        x, rest = arr[0], arr[1:]

        return x + solution(rest)

    else:

        # Base case

        return 0

現在的基本情況是當arr為空時(而不是當您傳遞了數組外部的索引時)。您計算空列表的總和,該列表只能在邏輯上通過0。遞歸情況將第一個元素從列表中拉出,并將其添加到列表其余部分的解決方案中。


查看完整回答
反對 回復 2023-10-05
  • 4 回答
  • 0 關注
  • 174 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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