閱讀時間預估:8分鐘
什麼是逆波蘭?
逆波蘭表示式又叫做字尾表示式。在通常的表示式中,二元運算子總是置於與之相關的兩個運算物件之間,這種表示法也稱為中綴表示。波蘭邏輯學家J.Lukasiewicz於1929年提出了另一種表示表示式的方法,按此方法,每一運算子都置於其運算物件之後,故稱為字尾表示。
大白話解釋:
給你一組數字,從左向右遍歷,如果遇到+-*/
那麼就逆序拿出運算子左邊的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
複製程式碼
下面通過畫圖的方式來分析求逆波蘭值的過程
通過上面的圖,我們可以很清晰的看出其規律,其實就是壓棧,出棧,壓棧,出棧的過程,那麼在JS中陣列的push
和pop
就可以實現。
程式碼實現過程:
方案一:
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());
}
複製程式碼
精簡程式碼封裝一:
<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>
複製程式碼
最終程式碼:
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 逆波蘭表示式求值進行驗證,如果您有更好的實現方案,也歡迎留言一起交流和討論。
希望我的分享對你能有幫助,如何對你有所啟發,以程式設計師最高禮遇點贊?評論加轉發的方式來鼓勵我,你的肯定是我前進的最大動力!
如果你想獲取前端整期學習視訊和資料掃一掃下面的二維碼,回覆學習即可免費領取,也希望在前端進階的路上,我們一起成長,一起進步!