中缀表达式转后缀表达式
1、初始化两个栈1:s1运算符号栈,s2:中间结果栈
2、从左至右扫描中缀表达式
3、遇到数字直接入s2
4、遇到运算符,比较其与s1栈顶符号的优先级
(1)如果s1为空,或者栈顶运算符为左括号'(',则直接将此运算符入栈
(2)否则,如果优先级比栈顶运算符高,则将运算符压入s1
(3)如果优先级小于等于栈顶运算符,则将s1栈顶运算符弹出并压入s2,转到4.1继续比较。
5、遇到括号
(1)如果是左括号'(',直接入s1
(2)如果是有括号')', 依次弹出s1栈顶符号,并压入s2,直到遇到左括号位置,并将这一对括号丢弃
重复2-5,直到表达式的最右边 将s1中剩余元素依次弹出并压入s2.
后缀表达式求值
(1) 从左向右扫描表达式,遇到数字,直接入栈
(2) 遇到运算符,弹出栈顶两个数,使用运算符计算,并将结果入栈。
(3) 重复上述操作,直到表达式最右端,最后运算得出的值即为表达式运算结果
public class Midfix2Suffix {
private static int ADD = 1;
private static int SUB = 1;
private static int MUL = 2;
private static int DIV = 2;
// 将表达式转为列表形式,方便后续操作
public List<String> getExpressionList(String expression) {
List<String> expressionList = new ArrayList<>();
int i = 0;
char ch = ' ';
StringBuilder tmp = new StringBuilder();
while (i < expression.length()) {
if ((ch = expression.charAt(i)) < 48 || (ch = expression.charAt(i)) > 57) {
expressionList.add("" + ch);
i++;
} else {
while (i < expression.length() && (ch = expression.charAt(i)) >= 48 && (ch = expression.charAt(i)) <= 57) {
tmp.append(ch);
i++;
}
expressionList.add(tmp.toString());
tmp = new StringBuilder();
}
}
return expressionList;
}
// 中缀表达式转后缀表达式
public List<String> ToSuffix(List<String> midList) {
Stack<String> symbolStack = new Stack<>();
// 整个算法过程中,resStack没有pop操作,且最后还需逆序输出,因此使用List表示
List<String> resStack = new ArrayList<>();
for (String item : midList) {
if (item.matches("\\d+")) {
resStack.add(item);
} else if ("(".equals(item)) {
symbolStack.push(item);
} else if (")".equals(item)) {
while (!"(".equals(symbolStack.peek())) {
resStack.add(symbolStack.pop());
}
symbolStack.pop();
} else {
while (!symbolStack.isEmpty() && priority(item) <= priority(symbolStack.peek())) {
resStack.add(symbolStack.pop());
}
symbolStack.push(item);
}
}
while (!symbolStack.isEmpty()) {
resStack.add(symbolStack.pop());
}
return resStack;
}
// 后缀表达式计算
public int calculator(List<String> suffixList) {
Stack<String> stack = new Stack<>();
for (String item : suffixList) {
if (item.matches("\\d+"))
stack.push(item);
else {
int num1 = Integer.parseInt(stack.pop());
int num2 = Integer.parseInt(stack.pop());
int res = 0;
switch (item) {
case "+":
res = num1 + num2;
break;
case "-":
res = num2 - num1;
break;
case "*":
res = num1 * num2;
break;
case "/":
res = num2 / num1;
break;
}
stack.push("" + res);
}
}
return Integer.parseInt(stack.pop());
}
// 返回运算符优先级
public int priority(String operation) {
return switch (operation) {
case "+" -> ADD;
case "-" -> SUB;
case "*" -> MUL;
case "/" -> DIV;
default -> 0;
};
}
}