最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Javascript尾遞歸編程的實(shí)現(xiàn)

 更新時(shí)間:2022年06月20日 10:17:05   作者:Jimmy0_0  
本文主要介紹了Javascript尾遞歸編程的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

尾遞歸編程思想

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

我們知道遞歸寫起來(lái)確實(shí)方便,邏輯也容易理解,最簡(jiǎn)單的斐波那契數(shù)列問(wèn)題,跳樓梯,一次只能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);
}

很明顯上述遞歸沒(méi)有任何優(yōu)化,利用函數(shù)堆棧來(lái)實(shí)現(xiàn)對(duì)上一結(jié)果的保存作為下一結(jié)果的支撐,函數(shù)開(kāi)銷大。

運(yùn)用緩存結(jié)果思想解決函數(shù)開(kāi)銷

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];
}

是解決了數(shù)據(jù)過(guò)大棧溢出問(wèn)題了,不過(guò)也同時(shí)帶來(lái)空間開(kāi)銷

迭代方法

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;
}

如果是復(fù)雜點(diǎn)的問(wèn)題迭代法是比較難想出來(lái)的。但凡可以實(shí)現(xiàn)迭代處理的方法可以用尾遞歸實(shí)現(xiàn),遞歸的實(shí)現(xiàn)更具有可讀性和簡(jiǎn)潔性。

尾遞歸實(shí)現(xiàn)

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

原理圖解

關(guān)于Javascript沒(méi)有實(shí)現(xiàn)尾遞歸優(yōu)化

Javascript由于某些原因,JavaScript引擎實(shí)現(xiàn)者認(rèn)為特性不合理,以及各大廠商的權(quán)力糾紛問(wèn)題,TC39提案仍未落實(shí)尾遞歸優(yōu)化方案。

如果要實(shí)現(xiàn)JavaScript尾遞歸優(yōu)化,需要采用蹦床函數(shù)輔助實(shí)現(xiàn),才能實(shí)現(xiàn)和迭代一樣避免棧溢出情況。

trampoline實(shí)現(xiàn)

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));

到此這篇關(guān)于Javascript尾遞歸編程的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Javascript尾遞歸內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

枞阳县| 仁布县| 平罗县| 寻乌县| 井冈山市| 岑巩县| 蓬莱市| 江山市| 松桃| 胶州市| 鹿泉市| 庐江县| 庆城县| 获嘉县| 宜宾市| 洞口县| 井研县| 文昌市| 河源市| 大丰市| 景洪市| 中牟县| 无为县| 乌拉特后旗| 慈溪市| 堆龙德庆县| 黄龙县| 石台县| 大邑县| 玛纳斯县| 抚州市| 饶平县| 昌吉市| 天峨县| 定州市| 洛扎县| 宜宾市| 大新县| 略阳县| 武乡县| 舞阳县|