中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Javascript尾遞歸編程怎么實現

發布時間:2022-06-20 11:48:28 來源:億速云 閱讀:138 作者:iii 欄目:開發技術

本篇內容介紹了“Javascript尾遞歸編程怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

尾遞歸編程思想

遞歸是編程中必不可少的一環,在算法和工程上會經常使用,但是隨著計算量的增大,函數堆棧會大量堆積上一函數上下文中的變量和方法,會導致主線程棧的空間不足而造成棧溢出錯誤,由于新的函數壓入堆棧后,上一函數仍然在堆棧中未被釋放,因此內存資源消耗會十分大,對性能也會有很大影響。

我們知道遞歸寫起來確實方便,邏輯也容易理解,最簡單的斐波那契數列問題,跳樓梯,一次只能1步或2步,跳n格有多少種方法

最容易的遞歸

// 限制條件 countOfStep>0
function jump(countOfStep) {
    if (countOfStep <= 0) return 0;
    function jumpRecursive(innerCountOfStep) {
        if (innerCountOfStep < 0) return 0;
        if (innerCountOfStep === 1 || innerCountOfStep === 0) return 1;
        return jumpRecursive(innerCountOfStep - 1) + jumpRecursive(innerCountOfStep - 2);
    }
    return jumpRecursive(countOfStep);
}

很明顯上述遞歸沒有任何優化,利用函數堆棧來實現對上一結果的保存作為下一結果的支撐,函數開銷大。

運用緩存結果思想解決函數開銷

function jumpWithoutFuncCost(countOfStep) {
    if(countOfStep<=0) return 0;
    const saves = new Array(countOfStep + 1).fill(0);
    [saves[0], saves[1]] = [1, 1];
    for (let i = 2; i <= countOfStep; i++) {
        saves[i] = saves[i - 1] + saves[i - 2];
    }
    return saves[countOfStep];
}

是解決了數據過大棧溢出問題了,不過也同時帶來空間開銷

迭代方法

function jumpIteritive(countOfStep) {
    if(countOfStep<=0) return 0;
    let [prefix, suffix] = [1, 1];
    for (let i = 2; i <= countOfStep; i++) {
        let temp = suffix;
        suffix += prefix;
        prefix = temp;
    }
    return suffix;
}

如果是復雜點的問題迭代法是比較難想出來的。但凡可以實現迭代處理的方法可以用尾遞歸實現,遞歸的實現更具有可讀性和簡潔性。

尾遞歸實現

function jumpTailRecursive(countOfStep, prev = 1, next = 1) {
    if(countOfStep<=0) return 0;
    if (countOfStep === 1) return next;
    return jumpTailRecursive(--countOfStep, next, prev + next);
}

原理圖解

Javascript尾遞歸編程怎么實現

關于Javascript沒有實現尾遞歸優化

Javascript由于某些原因,JavaScript引擎實現者認為特性不合理,以及各大廠商的權力糾紛問題,TC39提案仍未落實尾遞歸優化方案。

如果要實現JavaScript尾遞歸優化,需要采用蹦床函數輔助實現,才能實現和迭代一樣避免棧溢出情況。

trampoline實現

function jumpTailRecursiveTrampolined(countOfStep, prev = 1, next = 1) {
    if (countOfStep <= 0) return 0;
    if (countOfStep === 1) return next;
    return () => jumpTailRecursiveTrampolined(--countOfStep, next, prev + next);
}

function trampoline(F){
    return function(...args){
        F = F.bind(this, ...args);
        while (F instanceof Function) {
            F = F();
        }
        return F;
    }
}

const uniformLog = (element) => console.log(JSON.stringify(element, undefined, 4));
uniformLog(trampoline(jumpTailRecursiveTrampolined)(3));

“Javascript尾遞歸編程怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武强县| 兴国县| 肥西县| 衢州市| 泽库县| 陆河县| 宁强县| 茂名市| 达日县| 东海县| 石门县| 秦安县| 天水市| 无棣县| 湖北省| 宿州市| 龙江县| 长海县| 鄂托克前旗| 阳高县| 库尔勒市| 屏山县| 沂南县| 陈巴尔虎旗| 榆林市| 大丰市| 华阴市| 德格县| 察哈| 手游| 大厂| 右玉县| 鄂尔多斯市| 华蓥市| 清丰县| 阿荣旗| 新巴尔虎左旗| 肇东市| 全椒县| 山东| 柘荣县|