使用 memoization 加速遞迴
大家對費式(Fibonacci)數列都很熟悉。我們可以在 20 秒內寫出以下的函式。
var fibonacci = function(n) {
return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}
它可以執行,但是效率不高。它做了大量的重複計算,我們可以快取先前的計算結果來加快計算速度。
const fibonacci = (function() {
let cache = [0, 1]; // cache the value at the n index
return function(n) {
if (cache[n] === undefined) {
for (let i = cache.length; i <= n; ++i) {
cache[i] = cache[i - 1] + cache[i - 2];
}
}
return cache[n];
}
})()
也許,我們可以定義高階函式,來接受一個函式作為參數,並回傳一個函式回傳的暫存值。
const memoize = function(func) {
let cache = {};
return function() {
const key = JSON.stringify(Array.prototype.slice.call(arguments));
return key in cache ? cache[key] : (cache[key] = func.apply(this, arguments));
}
}
fibonacci = memoize(fibonacci);
這裡是 ES6 版本的 memoize 函式。
const memoize = function(func) {
const cache = {};
return (...args) => {
const key = JSON.stringify(args)
return key in cache ? cache[key] : (cache[key] = func(...args));
}
}
fibonacci = memoize(fibonacci);
我們可以將 memoize()
使用在其他地方
- GCD(最大公因數)
const gcd = memoize(function(a, b) {
let t;
if (a < b) t = b, b = a, a = t;
while (b != 0) t = b, b = a % b, a = t;
return a;
});
gcd(27, 183); //=> 3
- 階乘計算
var factorial = memoize(function(n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
})
factorial(5); //=> 120
學習更多關於 memoization:
MEET THE NEW JSTIPS BOOK
You no longer need 10+ years of experience to get your dream job.
Use the 100 answers in this short book to boost your confidence and skills to ace the interviews at your favorite companies like Twitter, Google and Netflix.
GET THE BOOK NOW
MEET THE NEW JSTIPS BOOK
The book to ace the JavaScript Interview.
A short book with 100 answers designed to boost your knowledge and help you ace the technical interview within a few days.
GET THE BOOK NOW