只允许一次函数调用
一次函数调用意味着在程序中只能执行一次特定函数的操作或代码。
编写一个名为 memoize
的函数,它接收另一个函数作为输入,并返回一个记忆化的版本。记忆化函数在接收到相同的输入时,不会重新计算结果,而是从缓存中返回已计算过的值。
假设提供的输入函数有以下三种类型:
sum(a: number, b: number): number
接收两个整数参数并返回它们的和。fib(n: number): number
计算第 n
个斐波那契数列项,遵循递归规则:fib(n) = fib(n - 1) + fib(n - 2)
(当 n <= 1
时返回 1)。factorial(n: number): number
计算阶乘,遵循递归规则:factorial(n) = n * factorial(n - 1)
(当 n <= 1
时返回 1)。示例 1:
输入:
"sum"
["call","call","getCallCount","call","getCallCount"]
[[2,2],[2,2],[],[1,2],[]]
输出:
[4,4,1,3,2]
示例 2:
输入:
"factorial"
["call","call","call","getCallCount","call","getCallCount"]
[[2],[3],[2],[],[3],[]]
输出:
[2,6,2,2,6,2]
示例 3:
输入:
"fib"
["call","getCallCount"]
[[5],[]]
输出:
[8,1]
0 <= a, b <= 10^5
1 <= n <= 10
callCount
10^5 次sum
, fib
, 或 factorial
type Fn = (...params: any) => any
function memoize(fn: Fn): Fn {
const map: Map<string, number> = new Map<string, number>()
return function(...args: any[]) {
const str = JSON.stringify(args)
if (map.has(str)) {
return map.get(str)
}
const result = fn(...args)
map.set(str, result)
return result
}
}
/**
* 示例用法:
* let callCount = 0;
* const memoizedSum = memoize(function (a: number, b: number) {
* callCount += 1;
* return a + b;
* })
* memoizedSum(2, 3) // 5
* memoizedSum(2, 3) // 5
* console.log(callCount) // 1
*/
注意:上述代码片段中的 memoize
函数实现需要对不同的输入函数类型进行适配,确保能够正确地缓存和检索计算结果。由于 TypeScript 类型系统在此处无法自动推断出具体函数的参数类型,因此实际实现中可能需要针对 sum
、fib
和 factorial
分别编写相应的记忆化封装函数,或者提供更精确的类型注解。