java实现中缀转后缀表达式
java实现中缀转后缀表达式
代码实现
public class Demo {
public static void main(String[] args) {
String expression = "1+((2+3)*4)-5";
List<String> strings = toList(expression);
List<String> suffixExression = toSuffixExression(strings);
System.out.println(suffixExression);
}
public static List<String> toSuffixExression(List<String> list) {
// 符号栈
Stack<String> operas = new Stack<>();
List<String> result = new ArrayList<>();
// 遍历中缀表达式
for (String s : list) {
// 如果是一个数直接入result
if (s.matches("\\d+")) {
result.add(s);
} else if ("(".equals(s)) {
// 如果是一个(
operas.push(s);
} else if (")".equals(s)) {
// 如果是一个),进行操作
while (!"(".equals(operas.peek())) {
result.add(operas.pop());
}
// pop掉(
operas.pop();
} else {
// 如果是操作符
// s的优先级比栈顶小:将operas的运算符弹出并加入result,再次和operas新的运算符比较
// 避免空栈,使用短路与
while (operas.size() != 0 && priority(operas.peek()) >= priority(s)) {
// 将operas的栈顶加入result
result.add(operas.pop());
}
// 将当前的元素入operas
operas.push(s);
}
}
// 遍历结束后,将operas中所有元素加入result
while (operas.size() != 0) {
result.add(operas.pop());
}
return result;
}
public static List<String> toList(String s) {
ArrayList<String> list = new ArrayList<>();
// 用于多位数拼接
StringBuilder str = new StringBuilder();
// 每遍历到一个字符,便放入c中
char c;
for (int i = 0; i <= s.length() - 1; i++) {
// 拿到每一个元素
c = s.charAt(i);
// 判断是不是数字
if (c < 48 || c > 57) {
// 如果是非数字
list.add("" + c);
} else {
// 考虑多位数问题
str.append(c);
// 避免最后一位数有数组下标越界异常
if ((i != s.length() - 1)) {
char next = s.charAt(i + 1);
if (next < 48 || next > 57) {
// 如果下一个是非数字
list.add(String.valueOf(str));
// 置空
str.delete(0, str.length());
}
} else {
list.add(String.valueOf(str));
}
}
}
return list;
}
// 计算运算符的优先级
public static int priority(String opera) {
int priority = -1;
// 预防栈顶元素为(
if (opera.equals("(")) {
return priority;
}
String[] operas = {"*", "/", "+", "-"};
if (opera.equals(operas[0]) || opera.equals(operas[1])) {
priority = 1;
} else if (opera.equals(operas[2]) || opera.equals(operas[3])) {
priority = 0;
} else {
throw new RuntimeException("运算符异常");
}
return priority;
}
}