逆波兰表达式(后缀表示法)计算实现
在逆波兰记法中,所有操作符置于操作数的后面,因此也被称为后缀表示法。逆波兰记法不需要括号来标识操作符的优先级。
后缀表示法的意思就是,为两个数字匹配一个计算符号,将这个符号放置在这两个数字的后方。
例子1:(30+4)×5-6 => 30 4 + 5 × 6 - => 164
例子2:(3+4)x5-6 => 3 4 + 5 * 6 - ==>29
逆波兰表达的好处是,不需要对符号的优先级进行排序
实现分析:
- 首先,需要对后缀表达式进行遍历,遍历过程中将数字push入栈,遇到符号时pop出栈顶的两个进行计算即可
- 将第一步计算的结果继续push入栈,直到遍历结束
package stack;
import java.util.ArrayList;
import java.util.List;
/**
* 这是一个逆波兰表达式,具体功能为传入一个逆波兰表达式,计算出其结果值
*
*/
public class PolandNotation {
public static void main(String[] args) {
//(30+4)×5-6 => 30 4 + 5 × 6 - => 164
// (3+4)x5-6 => 3 4 + 5 * 6 - ==>29
// 4*5-8+60+8/2 => 4 5 * 8 - 60 + 8 2 / +
String expression = "4 5 * 8 - 60 + 8 2 / +";
List<String> splits = getListString(expression);
ArrayStack stack = new ArrayStack(10);
// 遍历列表,将列表数字元素放入栈
for (String string:splits){
if (string.matches("\\d+")){
// 是数字,放入栈当中
stack.push(Integer.parseInt(string));
}
// 是运算符号,进行运算
else {
int num1 = stack.pop(); // 先出栈
int num2 = stack.pop(); // 后出栈
int result = 0;
// 当遇到了计算符号时,进行计算!
if (string.equals("+")){
result = num2 +num1;
}else if (string.equals("-")){
result = num2 - num1;
}else if (string.equals("/")){
result = num2 / num1;
}else if (string.equals("*")){
result = num2 * num1;
}else{
throw new RuntimeException("无效的计算符号!");
}
//将计算结果入栈
stack.push(result);
}
}
int res = stack.pop();
System.out.println(expression+"的计算结果为:"+res);
}
/**
* 需要将逆波兰表达式依次放入数字与运算符号,也就是表达式的格式化方法
*/
public static List<String> getListString(String expression){
String[] stringArray = expression.split(" ");
ArrayList<String> list = new ArrayList<>();
for (String element: stringArray){
list.add(element);
}
return list;
}
}
最终结果:
(30+4)×5-6 => 30 4 + 5 × 6 - => 164
(3+4)x5-6 => 3 4 + 5 * 6 - ==>29
4*5-8+60+8/2 => 4 5 * 8 - 60 + 8 2 / + ==>76