题目介绍
逆波兰表达式,也叫后缀表达式,是一种数学表示法,其中运算符在操作数之后。
表达式计算是编译原理、自然语言处理、文本分析等领域非常重要的问题,我们这里看一个相对中等的问题,逆波兰表达式。
LeetCode150.根据 逆波兰表示法,求表达式的值。说明:
1.有效的算符包括 +、-、*、/。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
2.注意两个整数之间的除法只保留整数部分。
3.可以保证给定的逆波兰表达式总是有效的。也即表达式总会得出有效数值目不存在除数为 0 的情况。
示例1
输入:tokens = [“2”,“1”,“+”,“3”,“*”]
输出:9
解释:使用逆波兰表达式得到的公式为:
(2+1) * 3
运算符在操作数后面,遇到数字继续往下遍历,遇到表达式,拿出来前两个数字,进行计算,然后继续遍历,直到就剩下一个数字,则为计算结果
解题思路
解题思路如下:
- 创建一个整数类型的栈
stack
用于存储操作数和中间结果。 - 遍历
tokens
数组中的每个字符串token
。 - 如果
token
是运算符,且长度为1(即是单个字符),则从栈中弹出两个整数,分别表示运算符的操作数。 - 根据运算符执行对应的运算,并将运算结果入栈。
- 如果
token
不是运算符,那么将其解析为整数,并将其入栈。 - 最终,栈中将只剩下一个元素,即计算结果,将其弹出栈并返回。
代码实现
代码如下(示例):
ipublic static int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for (String token : tokens) {
if (!Character.isDigit(token.charAt(0)) && token.length() == 1) {
/**
* 运算符,从栈中取出两个数进行运算!
*/
int b = stack.pop();
int a = stack.pop();
switch (token) {
/**
* 根据运算符的种类进行计算
* 将结果直接入栈!
*/
case "+":
stack.push(a + b);
break;
case "-":
stack.push(a - b);
break;
case "*":
stack.push(a * b);
break;
case "/":
stack.push(a / b);
break;
}
} else {
/**
* 整数直接入栈!
*/
stack.push(Integer.parseInt(token));
}
}
return stack.pop();
}
总结
在这段代码中,通过栈来保存操作数和中间结果,通过遍历逆波兰表达式的每个元素,根据运算符进行相应的计算,然后将计算结果入栈,直到遍历完整个逆波兰表达式。最后,从栈中弹出的元素就是整个表达式的计算结果。
这种实现方法充分利用了栈的后进先出特性,以及逆波兰表达式中运算符和操作数的有序性,从而避免了使用括号,并且可以在一次遍历中完成计算。