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

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

不帶引用和賦值的遞歸

不帶引用和賦值的遞歸

慕萊塢森 2022-08-25 14:51:09
這個問題在python(或類似)中被賦予了一個遞歸函數,可以重寫它,這樣它就不會引用自己。我做了一個簡單的例子,適用于這個問題。當然,不允許將其設置為非遞歸函數。它仍然必須執行相同的遞歸過程。def fact(n):  if n == 0:    return 1  return n * fact(n - 1)這也相當于一個簡寫。fact = lambda n: 1 if n == 0 else n * fact(n - 1)在示例中,我不應該在函數定義內部調用。fact編輯:其他約束:解決方案工作時,不必進行分配。沒有附加約束的一種解決方案(來自注釋)是創建兩個函數,它們交替調用彼此并有效地執行階乘。這是不允許的,因為它要求您在兩個變量中分配兩個函數。ab不需要賦值的函數的快速示例是f = lambda x: x + 1為了讓它執行在arugment上,我可以寫55(lambda x: x + 1)(55)因此,分配是沒有必要的。對此有什么提示嗎?還是我被騙到了一個不可能的問題?
查看完整描述

2 回答

?
茅侃侃

TA貢獻1842條經驗 獲得超21個贊

您可以使用 lambda 演算之類的東西來避免賦值和自引用,將兩者都替換為對匿名函數參數的訪問。例如:

fact = (lambda f: f(f))(lambda f: (lambda n: n*f(f)(n-1) if n else 1))

Ideone中測試。


下面提供了一些詳細信息,以獲取進一步的背景信息。

我知道lambda演算以強大(圖靈完備)但極簡主義的“編程語言”而聞名。它只使用變量的標識符,變量可以是綁定的(幾乎是函數參數)也可以是未綁定的(在談論表達式的某些部分時最相關)。所以這感覺就像一個很好的起點。

在 lambda 演算中表示遞歸的規范方法是使用不動點組合器。雖然該組合器可以在Python語法中天真地表達,但急切的評估會導致無限遞歸。

注釋中提到的 https://rosettacode.org/wiki/Y_combinator#Python 的代碼通過延遲其中一個遞歸調用直到函數實際被調用來避免這種無限遞歸。但我更愿意把對這種方法的詳細解釋留給一個單獨的答案。

在lambda演算中表達遞歸的核心思想是什么?將函數作為參數傳遞給自身。所以我從這個開始:

lambda f: f(f)  # λ f.f f

我需要向該函數傳遞另一個將函數作為值的函數。喜歡。該調用的結果應該是一個函數,該函數應將 an 作為計算階乘的參數。我的第一個近似值是將自己視為遞歸調用的表達式,所以我首先有這個:lambda f: …nf

(lambda f: f(f))(lambda f: (lambda n: n*f(n-1) if n else 1))

但后來我意識到這是錯誤的:它本身不是遞歸調用,因為它是接受參數的函數 。遞歸調用也是如此,導致我在開始時打印的解決方案。ffff(f)


查看完整回答
反對 回復 2022-08-25
?
catspeake

TA貢獻1111條經驗 獲得超0個贊

這很可能絕對不是問題所在,但是通過一些/魔術,您可以重建所調用的函數...inspecttypes


import types, inspect



def fact(n):

    frame = inspect.currentframe()

    fn = types.FunctionType(frame.f_code, frame.f_globals)


    if n == 0:

        return 1

    return n * fn(n - 1)



print(fact(10))


查看完整回答
反對 回復 2022-08-25
  • 2 回答
  • 0 關注
  • 87 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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