在上一篇中缀表达式转换为后缀表达式,我们已经将中缀表达式转换为了后缀表达式,接下来我们看看怎么根据后缀表达式计算出结果。
先创建一个数据结构,栈,作为存储。
同样,我们把后缀表达式看作是一个字符串,然后从左到右一个一个字符进行判断,规则如下:
- A.如果是数字,直接进栈
- B.如果是+或*,(加法或乘法),则将弹出栈顶两个元素,进行相加或相乘,将计算结果压入栈中
- C. 如果是-或/,(减法或除法),则先弹出一个数字为x,再弹出一个数字为y,然后y-x或y/x,最后将计算结果压入栈中
后缀表达式的字符循环完成之后,栈里应该就只有一个数字,这个数字就是我们要的计算结果。
以上一篇得到的后缀表达式 345*+678+9+ 为例,图示如下
- 数字345,直接进栈
- 遇到*号,5乘4,计算结果20进栈
- 遇到+号,20加3,计算结果23进栈
- 遇到数字6和7,依次进栈
- 遇到*号,7乘以6,计算结果42进栈
- 遇到数字8,直接进栈
- 遇到+号,8加42,计算结果50进栈
- 遇到数字9,直接进栈
- 遇到*号,9乘以50,计算结果450进栈
- 遇到+号,450加23,计算结果473进栈
后缀表达式字符判断完毕,把最后结果473输出
这个例子只有乘法和加法,请自行测试含有加减乘除的四则运算,自己动手,加深印象 +.+
代码如下:
// 后缀表达式计算结果
public static int cal (String s ) {
Stack<String> stack = new Stack<>();
char c;
Pattern p = Pattern.compile("\\d+");
for (int i = 0; i < s.length(); i++) {
c = s.charAt(i);
Matcher m = p.matcher(c+"");
// 数字直接进栈,然后分别判断加减乘除
if (m.find()) {
stack.push(c+"");
continue;
} else if (c == '+') {
int x = Integer.parseInt(stack.pop());
int y = Integer.parseInt(stack.pop());
stack.push((x+y)+"");
continue;
} else if (c == '*') {
int x = Integer.parseInt(stack.pop());
int y = Integer.parseInt(stack.pop());
stack.push((x*y)+"");
continue;
} else if (c == '-') {
int x = Integer.parseInt(stack.pop());
int y = Integer.parseInt(stack.pop());
stack.push((y-x)+"");
continue;
} else if (c == '/') {
int x = Integer.parseInt(stack.pop());
int y = Integer.parseInt(stack.pop());
stack.push((y/x)+"");
continue;
}
}
// 最后的结果,栈里只有一个元素,并且是数字
// peek方法只查看栈顶元素,不弹出; pop方法是查看并弹出栈顶元素
Matcher m1 = p.matcher(stack.peek());
if (stack.size() == 1 && m1.find())
return Integer.parseInt(stack.pop());
else
return -1;
}
把这个方法和上一篇的代码放一起,可以直接测试。
参考:https://www.cnblogs.com/jiu0821/p/6692878.html