记忆递归斐波那契函数
Memoize a recursive Fibonacci function
我创建了一个 withMemo
函数,该函数 returns 所提供函数的记忆版本。
const memoizedFn = withMemo(fn)
如何记住这个与递归一起使用的斐波那契函数?
const fibo = (n) => {
if (n <= 1) return 1
return fibo(n - 2) + fibo(n - 1)
}
实际上 withMemo(fibo)
并没有提高性能,因为 fibo
中的递归调用仍然指向未记忆的版本...
所以我必须更改 fibo 的声明才能使 momoization 工作:
const momoizableFibo = memoizer => {
const fibo = (n) => {
if (n <= 1) return 1
return memoizer(fibo)(n - 2) + memoizer(fibo)(n - 1)
}
return memoizer(fibo)
}
// momoizableFibo(withMemo)(50) // takes a ms
有没有一种方法可以记忆 fibo
(或与此相关的任何其他递归函数)而不用像我那样改变它的声明?
您可以使用 let fibo
而不是 const fibo
。然后用记忆版本替换 fibo
变量。通过更新 fibo
,嵌套调用现在将引用记忆的 fibo
函数而不是原始函数。
let fibo = (n) => {
console.log(n); // <- show original fibo calls
if (n <= 1) return 1;
return fibo(n - 2) + fibo(n - 1);
}
// update fibo variable so the nested fibo call calls the memoized version
fibo = withMemo(fibo);
console.log("fibo(3)", "//=>", fibo(3));
console.log("fibo(5)", "//=>", fibo(5));
console.log("fibo(2)", "//=>", fibo(2));
// simplified memoize function, only works for serializable parameters
function withMemo(fn) {
const cache = new Map();
return function (...args) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn(...args);
cache.set(key, result);
return result;
}
}
我创建了一个 withMemo
函数,该函数 returns 所提供函数的记忆版本。
const memoizedFn = withMemo(fn)
如何记住这个与递归一起使用的斐波那契函数?
const fibo = (n) => {
if (n <= 1) return 1
return fibo(n - 2) + fibo(n - 1)
}
实际上 withMemo(fibo)
并没有提高性能,因为 fibo
中的递归调用仍然指向未记忆的版本...
所以我必须更改 fibo 的声明才能使 momoization 工作:
const momoizableFibo = memoizer => {
const fibo = (n) => {
if (n <= 1) return 1
return memoizer(fibo)(n - 2) + memoizer(fibo)(n - 1)
}
return memoizer(fibo)
}
// momoizableFibo(withMemo)(50) // takes a ms
有没有一种方法可以记忆 fibo
(或与此相关的任何其他递归函数)而不用像我那样改变它的声明?
您可以使用 let fibo
而不是 const fibo
。然后用记忆版本替换 fibo
变量。通过更新 fibo
,嵌套调用现在将引用记忆的 fibo
函数而不是原始函数。
let fibo = (n) => {
console.log(n); // <- show original fibo calls
if (n <= 1) return 1;
return fibo(n - 2) + fibo(n - 1);
}
// update fibo variable so the nested fibo call calls the memoized version
fibo = withMemo(fibo);
console.log("fibo(3)", "//=>", fibo(3));
console.log("fibo(5)", "//=>", fibo(5));
console.log("fibo(2)", "//=>", fibo(2));
// simplified memoize function, only works for serializable parameters
function withMemo(fn) {
const cache = new Map();
return function (...args) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn(...args);
cache.set(key, result);
return result;
}
}