一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情。
前言
力扣第150题 逆波兰表达式求值 如下所示:
一、思路
毫无疑问现需要了解清楚什么是 逆波兰表示法?
逆波兰表示法
逆波兰表示法 是一种 后缀表示式,也就是说运算符会写在数字的后面。以示例一中的作为例子:
- 常见的中缀表达式:
((2 + 1) * 3) - 后缀表示式(逆波兰表示法):
((2 1 +) 3 *)
那后缀表示式有什么用呢?后缀表达式可以消除 括号 对与计算结果的影响,也就是说 ((2 1 +) 3 *) 与 2 1 + 3 * 是一样的
在了解了 逆波兰表示法 后,很明显可以发现运算符号只处理他之前的元素或者运算后的结果,如下图所示:
下图中的加号就是处理
2 + 1
下图中的称号是处理子式子的结果
3 * 3
经过上面的分析,我们不难发现这一题可以使用 栈 来存储需要计算值和计算后的结果,因为运算符始终都是取前面的两个值。大致的步骤人如下所示:
遍历表达式,会出现以下两种情况:
- 数字:直接入栈,用于之后的计算
- 预算符号:从栈中取出两个元素并按照运算符计算,再将计算后的结果入栈
二、实现
实现代码
需要注意的是,栈顶的元素是运算符计算的第二个元素!
实现的代码如下所示:
public int evalRPN(String[] tokens) {
Stack<Integer> numStack = new Stack<>();
//
for (String str : tokens){
if (isSign(str)){
// 出栈两个元素
Integer n2 = numStack.pop();
Integer n1 = numStack.pop();
int ret = calc(n1, n2, str);
numStack.push(ret);
} else {
// 碰到数字就入栈
numStack.push(Integer.valueOf(str));
}
}
return numStack.pop();
}
private boolean isSign(String str){
return "+".equals(str) || "-".equals(str) || "*".equals(str) || "/".equals(str);
}
/**、
* n1是前面的一个元素
*/
private int calc(Integer n1, Integer n2, String str){
int ret = 0;
if ("+".equals(str)){
ret = n1 + n2;
} else if ("-".equals(str)){
ret = n1 - n2;
} else if ("*".equals(str)){
ret = n1 * n2;
} else {
ret = n1 / n2;
}
return ret;
}
测试代码
public static void main(String[] args) {
String[] strings = {"2","1","+","3","*"};
new Number150().evalRPN(strings);
}
结果
三、总结
今天一次就过了,甚至没有写一个测试用例。
感谢看到最后,非常荣幸能够帮助到你~♥
如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~