题目
编写一个函数fn, 它接受另一个函数作为输入,并返回该函数的记忆化后的结果。
记忆函数是一个对于相同的输入永远不会被调用两次的函数。
相反,它将返回一个缓存值。
可以假设有3个可能的输入函数: sum、fib和factorial。
-
sum接收两个整型参数a和b,并返回a+b。假设如果参数(b, a)已经缓存了值,其中a != b,它不能用于参数(a, b)。例如,如果参数是(3, 2)和(2, 3),则应进行两个单独的调用。 -
fib接收一个整型参数n,如果n <= 1则返回1, 否则返回fib(n - 1) + fib(n - 2)。 -
factorial接收一个整型参数n,如果n <= 1则返回1,否则返回factorial(n - 1)*n
例子
例子1
输入;
fnName = "sum"
actions = ['call', 'call', 'getCallCount', 'call', 'getCallCount']
values = [[2, 2], [2, 2], [], [1, 2], []]
输出:[4, 4, 1, 3, 2]
解释:
cosnt sum = (a, b) => a + b;
const memoizedSum = memoize(sum);
memoizedSum(2, 2); // 'call' - 返回4。sum()被调用,因为之前没有使用参数(2, 2)调用过。
memoizedSum(2, 2); // 'call' - 返回4。没有调用sum(),因为前面有相同的输入。
// "getCallCount" - 总调用数: 1
memoizedSum(1, 2); // 'call' - 返回3。sum()被调用,因为之前没有使用参数(1, 2)调用过。
// "getCallCount" - 总调用数: 2
例子2
输入:
fnName = "factorial"
actions = ['call', 'call', 'call', 'getCallCount', 'call', 'getCallCount']
values = [[2], [3], [2], [], [3], []]
输出: [2, 3, 2, 2, 6, 2]
解释:
const factorial = (n) => (n <= 1) ? 1 : (n * factorial(n - 1));
const memoFactorial = memoize(factorial);
memoFactorial(2); // 'call' - 返回2
memoFactorial(3); // 'call' - 返回6
memoFactorial(2); // 'call' - 返回2。没有调用factorial(), 因为前面有相同的输入。
// 'getCallCount' - 总调用数: 2
memoFactorial(3); // 'call' - 返回6。没有调用 factorial(), 因为前面有相同的输入。
// 'getCallCount' - 总调用数:2
例子3
输入:
fnName = 'fib'
actions = ['call', 'getCallCount']
values = [[5], []]
输出: [8, 1]
解释:
fib(5) = 8 // 'call'
// "getCallCout" - 总调用数: 1
/**
* @param {Function} fn
* @return {Funciton}
**/
function memoize(fn) {
return function(...args) {
}
}
// 下面是对这个memoize 函数的解释
/**
let callCount = 0;
const memoizedFn = memoize(function (a, b) {
callCount += 1;
return a + b;
})
memoizedFn(2, 3) // 5
memoizedFn(2, 3) // 5
console.log(callCount) // 1
**/
解题:
function memoize(fn) {
const map = new Map()
return function(...args) {
const item = args.join(',')
if (!map.has(item)) {
map.set(item, fn(...args))
}
return map.get(item)
}
}