js 高級演算法 - 動態規劃

来源:http://www.cnblogs.com/star-wind/archive/2017/05/23/6893212.html
-Advertisement-
Play Games

主要是看了《數據結構與演算法》有所感悟,雖然這本書被挺多人詬病的,說這有漏洞那有漏洞,但並不妨礙我們從中學習知識。 其實像在我們前端的開發中,用到的高級演算法並不多,大部分情況if語句,for語句,swith語句等等,就可以解決了。稍微複雜的,可能會想到用遞歸去的解決。 但要註意的是遞歸寫起來簡潔,但實 ...


主要是看了《數據結構與演算法》有所感悟,雖然這本書被挺多人詬病的,說這有漏洞那有漏洞,但並不妨礙我們從中學習知識。

其實像在我們前端的開發中,用到的高級演算法並不多,大部分情況if語句,for語句,swith語句等等,就可以解決了。稍微複雜的,可能會想到用遞歸去的解決。

但要註意的是遞歸寫起來簡潔,但實際上執行的效率並不高。

我們再看看動態規劃的演算法:

動態規劃解決方案從底部開始解決問題, 將所有小問題解決掉, 然後合併成一個整體解決方案, 從而解決掉整個大問題 。

實例舉例  (計算斐波那契數列)

斐波那契數列指的是這樣一個數列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368........

這個數列從第3項開始,每一項都等於前兩項之和。

針對這個數列,可以用一個遞歸的函數去計算第n項 數值

 // 斐波那契數列
            function recurFib(n) {
                if(n < 2){
                    return n ;
                }else {
//                    document.write("第"+(n-1)+"次計算&nbsp;n-1="+(n-1)+recurFib(n-1)+'&nbsp;&nbsp;&nbsp;');
//                    document.write("n-2="+(n-2)+recurFib(n-2)+"<br>");
                    return recurFib(n-1)+recurFib(n-2)
                }
            }

確實是個非常簡潔的代碼,上面有被註釋的代碼 ,是用來列印出當n=多少,要執行多少次函數,不過明眼人一眼就能看出來執行的次數隨著n的變大,次數也會非常恐怖增長。

當n=5的時候,遞歸樹已經長的很大了……可以預見當n=10,甚至n=100的時候……

…………………………………………………………………………………………………………………………………………………………………………………………………………………………

明白了遞歸函數執行效率之差,我們再來看的動態規劃是如何做的

  function dynFib(n) {
            let val = [];
            for(let i = 0; i <= n; ++i){
                val[i]=0;
            }
            if(n ===1 || n  === 2){
                return 1;
            }
            else {
                val[1] =1;
                val[2] = 2;
                for(let i = 3; i <= n; ++i){
                    val[i] = val  [i-1] +val[i-2] ;
                }
            }
            return val[n-1]
        }

 

通過數組 val 中保存了中間結果, 如果要計算的斐波那契數是 1 或者 2, 那麼 if 句會返回 1。 否則,數值 1 2 將被保存在 val 數組中 1 2 的位置。

迴圈將會從 3 到輸入的參數之間進行遍歷, 將數組的每個元素賦值為前兩個元素之和, 迴圈結束, 數組的最後一個元素值即為最終計算得到的斐波那契數值, 這個數值也將作為函數的返回值。 

 

接下來可以寫個簡單的測試函數,來對比兩者的運行時間。

        // 定義一個測試函數,將待測函數作為參數傳入
        function test(func,n){
            let start = new Date().getTime();//起始時間
            let res = func(n);//執行待測函數
            document.write('<br>'+'當n='+n+'的時候&nbsp;'+res+'<br>');
            let end = new Date().getTime();//結束時間
            return (end - start)+"ms";//返回函數執行需要時間
        }

列印函數執行

     let time = test(recurFib,40);
        document.write(time);
        let time2 = test(dynFib,40);
        document.write(time2);

結果如下:

最後, 你或許已經意識到在使用迭代的方案計算斐波那契數列時, 是可以不使用數組的。

需要用到數組的原因是因為動態規划算法通常需要將中間結果保存起來。

以下是迭代版本的斐波那契函數義 

        function iterFib(n) {
            let last = 1;
            let nextLast = 1;
            let result = 1;
            for (let i = 2; i < n; ++i) {
                result = last + nextLast;
                nextLast = last;
                last = result;
            }
            return result;
        }

當然這個迭代版本的與數組的版本的效率也是相同的。

參考文獻   https://book.douban.com/subject/25945449/ 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 自己用 art-template 有些年頭了,最近在培養團隊學習 art-template 使用,發現有一個痛點比較難解決。 比如有一個模版,我們可以直接寫在頁面中,像這樣: 但如果這是個公用的模版,在很多頁面需要用到,那就不能直接寫在頁面中了,不然就得複製很多份了,那就只能寫到 js 文件里,做為 ...
  • 效果圖如下: HTML 文本源碼: base.js 源碼 1 /*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license 2 //@ sourceMappingURL=jquery.min.map 3 ...
  • 什麼是雪碧圖雪碧圖就是CSS Sprite,也有人叫它CSS精靈,是一種CSS圖像合併技術,就是把多張小圖標合併到一張圖片上,然後用css的background-position來顯示需要顯示的部分。 為什麼要用雪碧圖 可以減少載入網頁圖片時對伺服器的請求次數,提高頁面的載入速度,解決IE6滑鼠滑過 ...
  • 在javascript中toggle()為連續點擊事件,當裡面含有多個function(){}函數時,每次點擊依次執行裡面的function的函數,直至最後一個.隨後每次點擊都重覆對這幾個函數的輪番調用,toggle的語法如下 toggle(fn1,fn2,fn3·····fnN); 但當toggl ...
  • Node.js是基於Chrome JavaScript運行時建立的一個平臺,實際上它是對Google Chrome V8引擎進行了封裝,它主要用於創建快速的、可擴展的網路應用。 Node.js採用事件驅動和非阻塞I/O模型,使其變得輕量和高效,非常適合構建運行在分散式設備的數據密集型的實時應用。 如 ...
  • NPM
    [1]基本操作 [2]安裝依賴包 [3]查看及修改 [4]發佈依賴包 ...
  • 查看效果:http://hovertree.com/texiao/css3/43/代碼如下: web前端特效:http://www.cnblogs.com/jihua/p/webfront.html ...
  • 通過閱讀各路大神對web存儲locastorage和sessionstorage的用法解析,自己試用了一下,在此留個備忘。 在項目中,如果用到很多次storage,要存儲很多數據,就要把它封裝成函數了: (該函數系不知名大神所寫,如有侵犯原創,請聯繫我……) setStorage是存儲數據的,key ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...