解釋實現記憶化輔助函式


記憶化是一個輔助函式,或者可以說是一種透過跟蹤函式過去已經計算過的值來提高程式效率的技術。在本文中,我們將討論記憶化輔助函式以及不同的示例,並詳細討論所有示例,以便我們能夠更好地理解記憶化。

現在讓我們在下面的部分深入討論記憶化輔助函式,並瞭解其實現和解釋。

記憶化輔助函式簡介

記憶化是一種程式設計技術,用於透過跟蹤函式過去已經計算過的值來提高程式的時間複雜度和空間複雜度。透過將函式呼叫的結果儲存在快取中,程式效率得到提高。透過重複執行具有先前已計算過的相同引數的函式,我們經常浪費時間。然後,我們可以快取計算出的值,並在使用相同引數呼叫函式時直接返回它。

記憶化輔助函式的實現

在這裡,我們將探索大量的示例和解釋,以幫助您更好地理解記憶化輔助函式。

示例1

讓我們透過這個示例來了解記憶化輔助函式的工作原理,在這個示例中,我們將討論程式碼、輸出和解釋,以便更好地理解這個概念:

function add(num1,num2){
   for(let i=0;i<100000;i++){
   }
   return num1+num2;
}
console.log(add(5,4));
console.log(add(5,4));

在這裡,我們透過傳遞兩個引數 num1 和 num2 來定義函式 add,用於對整數 num1 和 num2 進行加法運算。在這個函式中,我們運行了 for 迴圈,然後返回兩個整數的和。

在這種情況下,我們呼叫了加法函式,但由於 for 迴圈,我們的函式花費了時間。我們使用相同的引數反覆呼叫函式。因此,如果我們使用記憶化來儲存加法的值,我們就能節省時間,然後返回快取的值。我們不需要為相同的引數再次計算加法值。

示例2

讓我們藉助程式碼和解釋來看看我們的函式確定 add(5,4) 的值所花費的時間:

function add(num1,num2){
   for(let i=0;i<100000;i++){
   }
   return num1+num2;
}
console.time("Time taken");
console.log(add(5, 4));
console.timeEnd("Time taken");

我們的函式花費了 14.441ms 的時間來對整數 5 和 4 進行加法運算。

透過使用記憶化技術,我們可以透過快取已經計算出的值,然後在使用相同引數呼叫函式時返回它來提高函式的效率。

示例3

現在讓我們討論如何利用記憶化技術來縮短重複使用相同引數執行函式所需的時間。

function memoizeFunction(func) {
   let storage = {};
   return function (val1, val2) {
      const val = val1.toString() + val2.toString();
      if (!storage[val]) {
         storage[val] = func(val1, val2);
      }
      return storage[val];
   }
}
function add(num1, num2) {
   for (let i = 0; i < 10000000; i++) {
   }
   return num1 + num2;
}
console.time("First time, time taken");

let func = memoizeFunction(add);
console.log(func(5, 4));
console.timeEnd("First time, time taken");
console.time("Second time, time taken");

func = memoizeFunction(add);
console.log(func(5, 4));
console.timeEnd("Second time, time taken");
console.time("Third time, time taken");

func = memoizeFunction(add);
console.log(func(5, 4));
console.timeEnd("Third time, time taken");

注意:**完成任務所需的時間可能會發生變化**。

在這個例子中,我們使用記憶化函式快取了之前計算的值。當我們第一次使用 func(4,5) 時,引數首先被轉換為字串形式,然後與計算出的值一起儲存在物件 'storage' 中。

此外,當使用相同引數呼叫函式時,它首先確定該引數是否已經存在於物件 'storage' 中。如果已經計算過,它就不會再次計算,而是直接返回物件 'storage' 中包含的值。

從輸出中我們可以看到,每次我們使用相同引數呼叫函式時,新增 5 和 4 所花費的時間都減少了。

每次花費的時間:

98.885 ms
83.375 ms
13.071 ms

因此,從輸出可以看出,記憶化技術幫助縮短了每次我們使用相同引數重複呼叫函式所需的時間。

示例4

讓我們透過斐波那契數來討論另一個記憶化輔助函式的示例。

function memoizeFunction(func) {
   let storage = {};
   return function (val) {
      const value = val.toString();
      if (!storage[value]) {
      storage[value] = func(val);
      }
      return storage[value];
   }
}
function fibonacci(num) {
   if (num === 0 || num === 1)
   return num;
   else
   return fibonacci(num - 1) + fibonacci(num - 2);
}
console.time("First time, time taken");

let func = memoizeFunction(fibonacci);
console.log(func(6));
console.timeEnd("First time, time taken");
console.time("Second time, time taken");

func = memoizeFunction(fibonacci);
console.log(func(6));
console.timeEnd("Second time, time taken");
console.time("Third time, time taken");

func = memoizeFunction(fibonacci);
console.log(func(6));
console.timeEnd("Third time, time taken");

如果沒有記憶化技術的幫助,斐波那契數列的執行需要指數級的時間。透過儲存以前的結果,我們可以獲得預定義的結果,從而減少對計算結果的進一步檢查,並將步驟數減少到線性。

結論

在本文中,我們瞭解到記憶化是一個輔助函式或一種技術,它透過跟蹤函式過去已經計算過的值來提高程式的效率。透過將函式呼叫的結果儲存在快取中,程式效率得到提高。然後,我們可以快取計算出的值,並在使用相同引數呼叫函式時直接返回它。

更新於:2023年3月17日

瀏覽量:290

開啟你的職業生涯

透過完成課程獲得認證

開始學習
廣告