一种优化递归算法的方法(javascript)
看书的时候看到了这个比较酷的方法,分享一下。
一、问题描述:代码如下,我们以计算阶乘(factorial)为例,当重复调用factorial(9),factorial(8),factorial(7)的时候,显然在factorial(9)已经计算了后面两个的值,factorial(8)和factorial(7)算是重复计算。目标就是对此进行优化。
function factorial(n) { if (n === 0) { return 1 } else { return n * factorial(n - 1) } } console.log(factorial(9)) console.log(factorial(8)) console.log(factorial(7))
二、优化方法:主体原理是将计算结果在函数内部缓存起来,后面的重复计算直接取缓存。
初步优化代码如下:
function memfactorial(n) { // 进行缓存 if (!memfactorial.cache) { memfactorial.cache = { '0': 1, '1': 1, } } // 进行计算 if (!memfactorial.cache.hasOwnProperty(n)) { memfactorial.cache[n] = n * memfactorial(n - 1) } return memfactorial.cache[n] } console.log(memfactorial(9)) console.log(memfactorial(8)) console.log(memfactorial(7))
改进:可是这样不够通用,在计算其他递归算法的时候,希望也能用这个函数,我们将其封装为通用函数。代码如下:
function memoize(fundmental, cache) { cache = cache || {} var shell = function (arg) { if (!cache.hasOwnProperty(arg)) { cache[arg] = fundmental(arg) } return cache[arg] } return shell } // 缓存该阶乘函数 var memfactorial = memoize(factorial, { '0': 1, '1': 1 }) console.log(memfactorial(9)) console.log(memfactorial(8)) console.log(memfactorial(7))
方法来源于:《高性能JavaScript》--Nicholas C.Zakas
伸手摘星,即使徒劳无功也不致满手污泥。