比如說我們要計算Fibonacci數列的值,公式為
F(0) = 0
F(1) = 1
F(n) = F(n-1), F(n-2)
用C++來實作並配合memoization的話程式如下
int fibonacci(int n) { if (n<2) return n; static map<int,int> mymap; map<int,int>::iterator it; it = mymap.find(n); if (it==mymap.end()) { int f = fibonacci(n-1) + fibonacci(n-2); mymap[n] = f; return f; } else return it->second; }
主要的概念在於使用 map 來儲存計算過的 f(n)。
上述的方法需要自己在程式中檢查傳入的參數是否有計算過,
然而人是懶惰的,在某些程式語言中可以將一個函數直接"升級",
獲得memoization的能力。
比如說下面是ypcat提供的python的範例
def memoize(f, cache={}): def g(*args): key = tuple(args) if key not in cache: cache[key] = f(*args) return cache[key] return g def fib(n): return n if n<2 else fib(n-1)+fib(n-2) fib = memoize(fib) print fib(300)
比C++更方便的地方在於使用了一個函數 memoize 來包裝遞迴函數,執行的時候還可以把 fib() 直接替換為包裝過的函數。
Python, C#, Java, Lisp 等支援 first-class function 的語言都能達成以上功能,
那C++有沒有辦法自動memoization呢? 我目前還不確定。
No comments:
Post a Comment