簡體   English   中英

Javascript 階乘 function 記憶

[英]Javascript factorial function memoization

我正在嘗試使用帶有記憶的階乘 function。 我從 object 中獲取了最大值,以減少遞歸調用的次數。 但問題是第一次調用我不知道這是否經過優化,因為第一次調用非常昂貴。 對此的任何見解都會很棒。

let cache = {0: 1};
function factMemoize(key) {
    if (!cache[key]) {
        let maxVal = Object.keys(cache).reduce(function (a, b) {
            return Math.max(a, b);
        });
        console.log(maxVal);
        while (key >= maxVal) {
            cache[key] = key * factMemoize(key - 1);
            maxVal++;
        }
    }
    return cache[key];
}

你不會因為記住這個而買太多東西,因為你只使用每個值一次。 在您調用函數之后,您確實擁有第二次調用的緩存,但我們通常認為記憶是發生在僅在函數期間存在的緩存中的事情。 對於這樣的事情,計算斐波那契數是一個經典的例子,其中記憶是對朴素遞歸函數的巨大改進。

話雖如此,在您的函數中,尚不清楚您為什么將對象用於緩存然后進行搜索。 您可以只使用一個數組,其中索引將是您要計算的數字。 您不需要搜索它,只需從數字開始並遞歸調用下一個較低的數字即可。 如果有緩存,它會返回。 例如:

 let cache = [1]; function factMemoize(key) { if (!cache[key]) { cache[key] = key * factMemoize(key - 1) } else { // just to demo cache: console.log("cache hit:", key) } return cache[key] } // only hits cache at the end console.log("6! = ", factMemoize(6)) // second call benefits from cache: console.log("8! = ", factMemoize(8))

正如@mark-meyer 在此線程中提到的那樣,記住結果沒有任何好處,因為在計算過程中每個值只會計算一次。 Mark 提供的解決方案非常適合稍后通過重新調用具有相同或不同值的階乘來重用該函數。 在這種情況下,您可以通過重用現有結果來加快流程並降低時間復雜度。

這是它在閉包中的樣子:

function factorialFn() {
  const cache = [];

  return function _factorial() {
    if (n < 2) {
      return 1;
    }
    if (cache[n]) {
      return cache[n];
    }
    return cache[n] = n * _factorial(n - 1);
  }
}

然后,您可以像這樣使用它:

const factorial = factorialFn();

factorial(5); // 120
factorial(7); // 5040


在第一次調用時,它會計算factorial(5)並將其保存在緩存中以備將來參考。

在第二次調用時, factorial(7)將執行7 * factorial(6)
which factorial(6)基本上是6 * the cached value of factorial(5)

function factorial(n, cache = {}) {
    if (n < 2) return 1;
    if (n in cache) return cache[n];
    return cache[n] = n * factorial(n - 1, cache);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM