前面我们介绍了什么是中缀、前缀和后缀表达式,还实现使用Java代码了中缀表达式转后缀表达式。这篇博客我们来介绍如何计算后缀表达式,并使用Java实现。
计算后缀表达式的流程:
-
从左至右扫描表达式,遇到数字时,将数字压入堆栈。
-
遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 和 栈顶元素),并将结果入栈。
-
重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。
-
代码示例:
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class Calculator {
//存储运算符和优先值键值对
static Map<Character, Integer> ops = new HashMap<>();
static {
//ops.put('(', 0);
ops.put('+', 1);
ops.put('-', 1);
ops.put('*', 2);
ops.put('/', 2);
}
public static Character getComputingResult(String expression){
Stack<Character> tempStack = transferNifixExpressionToPostfixExpression(expression);
Stack<Character> postfixExpressionStack = new Stack<>();
//这里千万不能用size()遍历栈,因为栈的大小一直在变小。
int count = tempStack.size();
for (int i = 0;i < count;i ++){
postfixExpressionStack.push(tempStack.pop());
}
Stack<Character> numberStack = new Stack<>();
char temp = 0;
int tempNum = 0;
int fNumber = 0;
int sNumber = 0;
//处理从后缀表达式栈中弹出来的每个字符
for (int i = 0;i < count;i ++){
temp = postfixExpressionStack.pop();
//如果字符为数字压入数字栈
if(temp >= 48 && temp <= 57){
numberStack.push(temp);
}else {
//这里需要注意运算数的前后顺序
sNumber = Integer.valueOf(String.valueOf(numberStack.pop()));
fNumber = Integer.valueOf(String.valueOf(numberStack.pop()));
//如果计算结果超过9,需要另外实现
if(temp == '+'){
tempNum = fNumber + sNumber;
}else if(temp == '-'){
tempNum = fNumber - sNumber;
}else if(temp == '*'){
tempNum = fNumber * sNumber;
}else if(temp == '/'){
//这里需要注意,因为实现的是简易版计算,这里的计算结果如果为浮点类型自动被截取为整数
tempNum = fNumber / sNumber;
}
numberStack.push(String.valueOf(tempNum).charAt(0));
}
}
return numberStack.pop();
}
private static Stack<Character> transferNifixExpressionToPostfixExpression(String nifixExpression){
//存储表达式的中间结果
Stack<Character> expStack = new Stack<>();
//存储运算符
Stack<Character> opStack = new Stack<>();
//把中缀表达式字符串转换为字符数组
char [] chars = new char[nifixExpression.length()];
nifixExpression.getChars(0, nifixExpression.length(), chars, 0);
//遍历数组,处理每一个表达式的字符
for(int i = 0;i < chars.length;i ++){
if(chars[i] >= 48 && chars[i] <= 57){
expStack.push(chars[i]);
}else {
if(opStack.isEmpty() || opStack.peek() == '('){
opStack.push(chars[i]);
}else {
if(chars[i] == '('){
opStack.push(chars[i]);
}else if(chars[i] == ')'){
while (opStack.peek() != '('){
expStack.push(opStack.pop());
}
opStack.pop();
}else {
while (ops.get(chars[i]) <= ops.get(opStack.peek())){
expStack.push(opStack.pop());
if(opStack.size() == 0)break;
}
opStack.push(chars[i]);
}
}
}
}
opStack.forEach(character -> {
expStack.push(character);
});
// StringBuilder stringBuilder = new StringBuilder("");
// expStack.forEach(character -> {
// stringBuilder.append(character);
// });
return expStack;
}
public static void main(String[] args) {
System.out.println(getComputingResult("(5+2)*1-4"));
}
}
- 输出:
3
- 注意这里是实现的简易版计算器,全程计算只支持一位整数。