持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
前言
继续学习栈与队列,今天做leetcode150题.逆波兰表达式求值。分享后缀表达式相关知识。
题目
废话不多说了,先上题目:
题目就是根据逆波兰表示法,求表达式的值。不过题目限制好了条件,表达式总会得出有效数值且不存在除数为 0 的情况。
后缀表达式
可能大家听到逆波兰表达式会有些懵,其实逆波兰表达式并不是什么高深的概念,就是我们数据结构中熟悉的后缀表达式,是栈的一种很好的实现。
那么我们也许会觉得普通的写法(也就是中缀表达式)非常好了,便于理解。为什么要有后缀表达式呢?
由于计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序,所以逆波兰式在计算机看来是比较简单易懂的结构。
中缀表达式转后缀表达式
- 字母直接输出
- 栈空直接入栈
- 遍历时遇到"+"或者"-"需要退栈(弹出),退到栈中遇到"+"或者"-"停止,将栈中的"+"或者"-"输出,自己入栈;或者遇到"("停止,将自己入栈。
- 遍历时遇到")"需要退栈,遇到"("停止,将"("弹出栈。
后缀表达式的计算
从左到右扫描表达式,遇到数字入栈,遇到操作符取出栈顶的两个元素进行操作,然后将结果压入栈。
解题方法
了解了中缀表达式的一些基本知识后,我们就可以开始做题啦。后缀表达式的计算与1047.删除字符串中的所有相邻重复项有一些相似,遇到操作符取出栈顶的两个元素进行操作。
代码实现
/**
* @param {string[]} tokens
* @return {number}
*/
var evalRPN = function(tokens) {
const s = new Map([
["+", (a, b) => a * 1 + b * 1],
["-", (a, b) => b - a],
["*", (a, b) => b * a],
["/", (a, b) => (b / a) | 0]
]);
const stack = [];
for (const i of tokens) {
if(!s.has(i)) {
stack.push(i);
continue;
}
stack.push(s.get(i)(stack.pop(),stack.pop()))
}
return stack.pop();
};