用文字记录生活,留下美好瞬间
原创

记忆函数

共 1,724 字,需阅读 4 分钟
2018/11/02 上午
252 次阅读

#编写记忆化函数

#问题描述

编写一个名为 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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
示例 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
  • 最多进行 10^5 次函数调用
  • 最多尝试访问 callCount 10^5 次
  • 输入函数只能是 sum, fib, 或 factorial

#解决方案

          
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
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 类型系统在此处无法自动推断出具体函数的参数类型,因此实际实现中可能需要针对 sumfibfactorial 分别编写相应的记忆化封装函数,或者提供更精确的类型注解。

自由转载 - 署名 - 非商业性使用
https://zhangwurui.cn/article/31
0/0条看法
访客身份
在下有一拙见,不知...
期待你的捷足先登