中缀式向后缀式转化时,会使用栈这种结构来存储符号;而对于数字则是直接输出,转换的规则如下:
规则:从左向右扫描
-
遇到数字,直接输出
-
遇到'(',直接入栈
-
遇到')',进行括号匹配——符号依次出栈,直到遇到'('
-
若当前符号优先级大于栈顶元素,则当前符号入栈
-
若当前符号优先级小于、等于栈顶符号,栈顶符号依次出栈,直到当前符号优先级大于栈顶元素(或符号栈为空),将其入栈
-
遍历结束后,判断符号栈中是否还有元素,若有,将其全部输出即可
这样就完成了中缀式向后缀式的转换
代码如下:
package com.csdn;
import java.util.Stack;
/**
* @Author KING
* @Date 2022/6/15 22:29
* @Version 1.0
*/
public class Infix2SuffixTest {
// 符号栈
private static Stack<Character> symbolStack = new Stack<>();
// 优先级
public static int priority(char a) {
if (a == '(') {
return 0;
} else if (a == '+' || a == '-') {
return 1;
} else {
return 2;
}
}
// 比较符号的优先级 a的优先级比b高,就返回true
public static boolean compare(char a, char b) {
return priority(a) > priority(b);
}
// 判断是否为符号,注意:不包括')'
public static boolean isSymbol(char cur) {
return (cur == '+' || cur == '-' || cur == '*' || cur == '/' || cur == '(');
}
// 中缀式转化为后缀式
public static String infix2Suffix(String exp) {
StringBuffer res = new StringBuffer();
int idx = 0;
while (idx < exp.length()) {
char cur = exp.charAt(idx);
// 如果是符号,不包括')'
if (isSymbol(cur)) {
// 如果符号栈为空 或者 为'(' 符号直接存入符号栈
if (symbolStack.isEmpty() || cur == '(') {
symbolStack.push(cur);
idx++;
} else if (compare(cur, symbolStack.peek())) {
// 如果优先级大于原符号栈栈顶元素,存入符号栈
symbolStack.push(cur);
idx++;
} else {
// 如果优先级小于或等于原栈顶的符号,不断弹出栈顶元素直到栈顶元素小于当前符号优先级或者栈为空
while (!symbolStack.isEmpty() && !compare(cur, symbolStack.peek())) {
append(res, symbolStack.pop());
// res.append(symbolStack.pop());
}
// 当前符号入栈
symbolStack.push(cur);
idx++;
}
} else if (Character.isDigit(cur)) { // 如果是数字直接存入返回的字符串中
StringBuffer ret = new StringBuffer();
// 如果数字为多位
while (Character.isDigit(exp.charAt(idx))) {
ret.append(exp.charAt(idx++));
if (idx >= exp.length()) {
break;
}
}
res.append(ret);
// 规范输出格式
res.append(' ');
} else { // 如果是')'
// 不断的弹出栈元素并输出直到遇到左括号结束
while (!symbolStack.isEmpty() && symbolStack.peek() != '(')
{
append(res, symbolStack.pop());
// res.append(symbolStack.pop());
}
if (!symbolStack.isEmpty()) {
symbolStack.pop(); //退出左括号
}
idx++;
}
}
// 符号栈内如果还有符号未出栈,直接存入输出字符串中
while (!symbolStack.isEmpty()) {
append(res, symbolStack.pop());
// res.append(symbolStack.pop());
}
return res.toString();
}
public static void append(StringBuffer str, char ch) {
str.append(ch);
str.append(' ');
}
public static void main(String[] args) {
// String s = Infix2Suffix("1+2*3+(4*5+6)*7");
String s = infix2Suffix("(2*(9+6/3-5)+4)");
System.out.println(s);
}
}