javascript - 记忆递归斐波那契函数
问题描述
我创建了一个withMemo
函数,它返回所提供函数的记忆版本。
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
嵌套调用现在将引用 memoizedfibo
函数而不是原始函数。
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;
}
}
推荐阅读
- python-3.x - 在python中查找给定列表的所有子序列的有效方法是什么?
- java - java枚举异常
- google-chrome - 将 Chrome OS 键盘快捷键与普通的 3rd 方键盘一起使用?概览模式?
- shell - 有什么方法可以自动制作 shell 脚本别名?
- react-native - 访问 redux 持久化外部组件
- search - 为什么 Shift+F3 在 Notepad++ 中停止工作?
- python - Discord BOT with Python,如何让它在我们发送命令的频道中回复(完成)
- c# - Blazor 字段为空
- linux - 从 s3 存储桶下载多个大于某个时间戳的文件
- python - Python Tkinter - 如何在画布中包含小部件?