簡體   English   中英

算術運算符的遞歸定義:如何記憶/緩存?

[英]Recursive definition of arithmetic operators: How to memoize / cache?

所有算術運算符都基於所有自然數都有后繼這一事實。 出於教育目的,我將這個想法實現為 Python 函數:

# recursive definition of arithmetic operators

a = 2
b = 3  # larger numbers won't work: RecursionError


def successor(n):
    """ returns n + 1. All other functions use successor recursively """
    return n + 1


def sum(n, m):
    """ sum a + b """
    if m == 0:
        return n
    if m == 1:
        return successor(n)
    else:
        return successor(sum(n, m - 1))

print(f"sum({a}, {b}) = {sum(a,b)}")


def product(n, m):
    """ multiplication n*m"""
    if m == 0:
        return 0
    elif m == 1:
        return sum(n, 0)
    else:
        return sum(product(n, m - 1), n)

print(f"product({a}, {b}) = {product(a, b)}")


def power(n, m):
    """ power n**m"""
    
    if m == 0:
        return 1
    elif m == 1:
        return product(n, 1)
    else:
        return product(power(n, m - 1), n)

print(f"power({a}, {b}) = {power(a, b)}")


def up_arrow_2(n, m):
    """ up_arrow operator 2nd degree: n**(n**( ....) m times """
    if m == 0:
        return 1
    elif m == 1:
        return power(n, 1)
    else:
        return power(up_arrow_2(n, m - 1), n)

print(f"up_arrow_2({a}, {b}) = {up_arrow_2(a, b)}")


def up_arrow_3(n, m):
    """ up_arrow operator 3rd degree"""
    if m == 0:
        return 1
    elif m == 1:
        return up_arrow_2(n, 1)
    else:
        return up_arrow_2(up_arrow_3(n, m - 1), n)

print(f"up_arrow_3({a}, {b}) = {up_arrow_3(a, b)}")

這適用於最多a=2b=3的數字,然后在計算up_arrow_3(2, 4)時會發生maximum recursion depth exceeded (原因很明顯)。

如果我將行return n**m作為power function 中的第一行插入,則可以計算出更大的數字。 因此,緩存中間結果似乎是一個很有前途的解決方案。

為了擴展到更大的數字,我嘗試使用裝飾器 class 進行記憶,例如

class Memoize:
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
    def __call__(self, *args):
        if args not in self.memo:
            self.memo[args] = self.fn(*args)
        return self.memo[args]

並裝飾功能 - 沒有成功。

我正在尋找一個想法,如何編寫另一個裝飾器來執行所需的緩存並允許更大的輸入數字 a、b。

以下代碼將解決您的問題。

def memoize(func):
    cache = {}
    def memoize_inner(*args, **kwargs):
        str_args = f"{args}{kwargs}"
        return cache.get(str_args, func(*args, **kwargs))

    return memoize_inner

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM