閉包的應用斐波拉契數列為例詳細講解

2021-07-10 23:24:09 字數 3083 閱讀 6715

閉包是乙個受到保護的變數空間.

從字面意思來看就是封閉和包裹

在函式中定義的變數,在函式外部無法訪問,因此這個函式就構成閉包

###特點:

在函式體內部允許訪問外部的變數,但是外部不能訪問外部的變數

###要解決閉包的什麼問題

就是要訪問到它的資料

###怎麼樣訪問閉包中的資料

兩個模型:

返回乙個函式,用這個函式獲得資料

返回乙個物件,這個物件包含函式,來操作這個資料

##閉包的應用有兩個模型

1.實現私有資料

2.實現快取資料

2.1閉包做快取

2.2函式名做快取

但是這樣做的效能非常低,我們可以測試下呼叫一次,需要運算多少次

var count = 0;//計數器,只要呼叫一次函式,就讓count++

當fib(1)的時候,執行1次,fib(2),執行3次,

依次類推 1,3,5,9,15,25

根據運算結果,如果求10項需要運算177次

這樣效能會有非常大的問題,每一次計算都要分兩步去完成,而且有個特點不管有沒有算過都要算一遍,都要這樣去計算,那麼如果計算的數字非常大會影響到我們計算的結果

###怎麼樣提高效率呢,讓算過的不再算

把這個函式寫成乙個自呼叫函式

利用陣列快取,因為存的只是資料

var count;

var fib = (function () else else

arr[n] = res;//將計算的結果放到陣列中,那麼下一次在計算的時候直接拿來用,就不用重新計算了

//其實這裡使用鍵值對做快取,取的時候是取出來n,返回也是給n,沒有用push

為啥都是計算3次

因為我們都是直接從快取中去取,而不是通過遞迴去計算

但是用迴圈體現不出差異性,因為快取了,已經計算出了,就不會在計算,等下再給大家畫**釋下為什麼是3次,現在先讓大家體會下這個差異性

0原來是執行177次,現在只要19次,

之前輸入100會崩潰,現在輸入100只要199次

現在的差異看的很明顯了吧,

利用快取功能很大的提高了效率

大家也可以自己做下測試,原理很簡單就是用乙個陣列將已經計算過的值存起來

現在我們再看看為啥都是計算三次吧

因為前兩次[0]和[1]次迴圈已經有值了,從[2]開始,前兩個的值已經有了,所以不用再遞迴了,

每次要做的事情就是先檢查有沒有,沒有再進行運算,運算就遞迴兩次,

遞迴兩次就累積兩次得到的結果馬上放回去,加上當前的計算,一共是三次

下面來看看沒有用閉包的斐波拉契數列

果然有對比才有傷害啊啊啊

接下來再寫個改良版帶有快取的函式

之前是閉包做的快取,我們做實際開發時沒必要

函式也是物件,把共享的資料放到函式名裡

var fib = function (n)  else  else 

fib[n] = res;

fib.len++;//也可以用slice

return res;

}};fib.len = 0;//給函式新增乙個屬性len

優點把閉包去掉了,用函式名儲存資料

缺點:這個函式名誰都可以訪問,誰都可以修改這個資料

但是用閉包優點是除了fib這個函式誰都不能訪問

順便一提: jquery裡面有個createcache也是用這種實現的哦

利用沙箱模式進行優化,保護資料

矩陣快速冪(以斐波那契數列為例)

問題描述 小 w 發現了乙個神奇的數列 1 2 3,1 1,2 1 這就是著名的 fibonacci sequence 眾所周知,小 m 的數學超級超級好,於是給小 w 出了一道題 給小 w 兩個數 x,y,其中 x y 2 31 1。小 w 任務就是求出 fibonacci 數列第 x y 項的和...

以斐波那契數列為例 淺嚐記憶化搜尋

記憶化搜尋 演算法上依然是搜尋的流程,但是搜尋到的一些解用動態規劃的那種思想和模式作一些儲存。一般說來,動態規劃總要遍歷所有的狀態,而搜尋可以排除一些無效狀態。更重要的是搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。記憶化演算法在求解的時候還是按著自頂向下的順序,...

以斐波那契數列為例帶你入門動態規劃

我們先來使用遞迴的方法實現斐波那契數列 遞迴解決斐波那契問題 public static int f int n 遞迴求值的缺點是什麼呢?就是大量數值會被重複計算。舉個例子,我們在計算f 5 的時候計算了f 4 和f 3 在計算f 4 的時候又計算了f 3 和f 2 這裡的f 4 就被重複計算了。如...