【干货】阶乘算法的缓存

1、常规算法

常规算法看下面这个就够了,已经很全面了!分别介绍了4种方法。

js实现阶乘问题

2、缓存算法

上面没有考虑到缓存,举个例子先算了factorialize(4),现在要算factorialize(5),只需要在factorialize(4)的基础上计算就行了,不用从头开始计算。

【如果只使用一次,那就不用缓存,用的话反而增加内存开销。如果要多次使用,那就用缓存,可以明显提升运行效率。】

  • 1、无缓存
// 未使用缓存
const factorial = function f(num) {
  if (num < 0) {
        return -1;
    } else if (num === 0 || num === 1) {
        return 1;
    } else {
        for (let i = num - 1; i >= 1; i--) {
            num *= i;
        }
    }
    return num;
};
// 或者
const factorial = function f(num) {
  if (num < 0) {
    return -1;
  } else if (num === 0 || num === 1) {
    return 1;
  } else {
    return (num * f(num - 1));
  }
};
复制代码
  • 2、数组缓存
const mapArr = [1, 1];

const factorial = function f(num) {
  if (num < 0) {
    return -1;
  }
  if (num <= mapArr.length - 1) {
    return mapArr[num];
  } else {
    let rst = mapArr[mapArr.length - 1];
    for (let n = mapArr.length; n <= num; n++) {
      rst *= n;
      mapArr[n] = rst;
    }
    return rst;
  }
}
console.log(factorial(4));  // 24
console.log(mapArr);        // [ 1, 1, 2, 6, 24 ]
console.log(factorial(5));  // 120
console.log(mapArr);        // [ 1, 1, 2, 6, 24, 120 ]

复制代码
  • 3、map缓存

// 如果不喜欢用数组来缓存,也可以使用map。
// 上面是用数组来缓存,下面使用map来缓存
const map = {
  0: 1,
  1: 1,
}
const factorial2 = function f(num) {
  if (num < 0) {
    return -1;
  }
  const len = Object.keys(map).length;
  if (num <= len - 1) {
    return map[num];
  } else {
    let rst = map[len - 1];
    for (let n = len; n <= num; n++) {
      rst *= n;
      map[n] = rst;
    }
    return rst;
  }
};
console.log(factorial2(4));   // 24
console.log(map);             // { '0': 1, '1': 1, '2': 2, '3': 6, '4': 24 }
console.log(factorial2(5));   // 120
console.log(map);             // { '0': 1, '1': 1, '2': 2, '3': 6, '4': 24, '5': 120 }

复制代码

3、代理模式实现缓存

上面的实现会更改原函数,有没有什么方法可以不更改原函数而达到缓存的效果呢?—————答案:代理模式!

// 阶乘
const factorial = function f(num) {
  if (num < 0) {
    return -1;
  } else if (num === 0 || num === 1) {
    return 1;
  } else {
    return (num * f(num - 1));
  }
};

// 缓存代理函数
const proxyFunc = function (fn) {
  const cache = {};  // 缓存对象
  return function (num) {    
    if (num in cache) {
      return cache[num];   // 使用缓存代理
    }
    return cache[num] = fn.call(this, num);
  }
};

// 使用代理
const proxyFactorial = proxyFunc(factorial);
console.log(proxyFactorial(5)); // 120
console.log(proxyFactorial(5)); // 缓存取 120

复制代码

上面只会缓存曾经计算过的值(比如5),如果要缓存所有小于等于计算值的值(0-5),那就要修改一下代理函数,那么这个代理函数就只能为阶乘服务,请自行编码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值