前端菜鳥的每週一道算法題(一) - 逆波蘭表達式求值

閱讀時間預估:8分鐘前端

什麼是逆波蘭?

來自百度百科的解釋:程序員

逆波蘭表達式又叫作後綴表達式。在一般的表達式中,二元運算符老是置於與之相關的兩個運算對象之間,這種表示法也稱爲中綴表示。波蘭邏輯學家J.Lukasiewicz於1929年提出了另外一種表示表達式的方法,按此方法,每一運算符都置於其運算對象以後,故稱爲後綴表示。數組

大白話解釋:bash

給你一組數字,從左向右遍歷,若是遇到+-*/那麼就逆序拿出運算符左邊的2個數字進行運算,運算完以後繼續放裏面,繼續遍歷循環,直到結束,前提是要遵照最基本的四則運算。學習

例如
輸入:["2","1","+",3,"/"]
逆波蘭值爲:
(2+1)/3 = 1

輸入:["4","13","5","/","+"]
逆波蘭值爲:
4+(13/5) = 6

輸入:["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
逆波蘭值爲:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
複製代碼

下面經過畫圖的方式來分析求逆波蘭值的過程ui

經過上面的圖,咱們能夠很清晰的看出其規律,其實就是壓棧,出棧,壓棧,出棧的過程,那麼在JS中數組的 pushpop就能夠實現。

代碼實現過程:lua

方案一:spa

var evalRPN = function (tokens) {
    // 定義一個數組棧
    let stack = [];
    for (let item of tokens) {
        switch (item) {
            case '+':
                let a1 = stack.pop();
                let b1 = stack.pop();
                stack.push(b1 + a1);
                break;
            case '-':
                let a2 = stack.pop();
                let b2 = stack.pop();
                stack.push(b2 - a2);
                break;
            case '*':
                let a3 = stack.pop();
                let b3 = stack.pop();
                stack.push(b3 * a3);
                break;
            case '/':
                let a4 = stack.pop();
                let b4 = stack.pop();
                stack.push(parseInt(b4 / a4));
                break;
            default:
                stack.push(parseInt(item));
        }
    }
    return parseInt(stack.pop());
}
複製代碼

精簡代碼封裝一:3d

<script>
var evalRPN = function (tokens) {
    // 運算規則
    var caculate = function (right, left, operator) {
        switch (operator) {
            case '+':
                return Number(left) + Number(right);
            case '-':
                return Number(left) - Number(right);
            case '*':
                return Number(left) * Number(right);
            default:
                return parseInt(left / right);
        }
    }
    // 判斷是不是 + - * /
    function isOperator(str) {
        return ["+", "-", "*", "/"].includes(str);
    }
    // 定義一個棧用來存放數據
    let stack = [];
    for (item of tokens) {
        // 遍歷傳過來的tokens並經過三目運算來計算值
        isOperator(item) ? stack.push(caculate(stack.pop(), stack.pop(), item)) : stack.push(parseInt(
            item));
    }
    return stack.pop();
}

var data = ["2", "1", "+", "3", "*"];
console.log(evalRPN(data)); 

正確答案:9
</script>
複製代碼

最終代碼:code

var evalRPN = function (tokens) {
    // 定義一個數組棧
    let stack = [];
    for (let item of tokens) {
        switch (item) {
            case '+':1 = ;
                stack.push(stack.pop() + stack.pop());
                break;
            case '-':
                stack.push(-stack.pop() + stack.pop());
                break;
            case '*':
                stack.push(stack.pop() * stack.pop());
                break;
            case '/':
                let right = stack.pop();
                stack.push(parseInt(stack.pop() / right));
                break;
            default:
                stack.push(parseInt(item));
        }
    }
    return parseInt(stack.pop());
}
var data = ["2", "1", "+", "3", "*"];
console.log(evalRPN(data));
// 輸出答案爲:9
</script>
複製代碼

小夥伴們能夠複製以上代碼到LeetCode 逆波蘭表達式求值進行驗證,若是您有更好的實現方案,也歡迎留言一塊兒交流和討論。

但願個人分享對你能有幫助,如何對你有所啓發,以程序員最高禮遇點贊💓評論加轉發的方式來鼓勵我,你的確定是我前進的最大動力!

若是你想獲取前端整期學習視頻和資料掃一掃下面的二維碼,回覆學習便可免費領取,也但願在前端進階的路上,咱們一塊兒成長,一塊兒進步!

相關文章
相關標籤/搜索