java中缀表达式转后缀表达式
- 转自尚硅谷韩顺平老师课堂内容
public class Calculator {
public static void main(String[] args) {
//先定义一个逆波兰表达式(3+4)*5-6 =》 3 4 + 5 * 6 —-
String sunffixExpression = "3 4 + 5 * 6 -";
List<String> list = getListString(sunffixExpression);
System.out.println(list);
int res = calculate(list);
System.out.println(res);
String inffixExpression = "1+((2+3)*4)-5";
List<String> lStrings = getInffixExpressionList(inffixExpression);
System.out.println("前缀表达式"+lStrings);
List<String> sufixStrings = parseSunffixList(lStrings);
System.out.println("后缀表达式"+sufixStrings);
System.out.println("计算结果"+calculate(sufixStrings));
}
//将中缀表达式字符串转换为后缀表达式
public static List<String> parseSunffixList(List<String> ls){
//首先定义两个栈
Stack<String> s1 = new Stack<String>();//符号栈
//因为s2在整个过程中没有出栈操作,所以使用arrlist
// Stack<String> s2 = new Stack<String>();//存储中间结果的栈
List<String> s2 = new ArrayList<String>();
//遍历ls
for(String item:ls) {
//如果是一个数,加入s2
if(item.matches("\\d+")) {//正则表达式
s2.add(item);
}else if(item.equals("(")) {
s1.push(item);
}else if(item.equals(")")) {
//如果遇到右括号,则依次弹出s1栈顶的操作符,并压入s2;知道遇见左括号
while(!s1.peek().equals("(")) {
s2.add(s1.pop());
}
s1.pop();//左括号弹出
}else {
//当item优先级小于等于s1栈顶的他优先级,s1栈顶的操作符加入s2中。并循环比较
while(s1.size() != 0&& OperationPrioty.getPrioty(s1.peek())>=OperationPrioty.getPrioty(item)) {
s2.add(s1.pop());
}
s1.push(item);
}
}
//将s1总剩余的操作加入s2
while(s1.size() != 0) {
s2.add(s1.pop());
}
return s2;
}
//获取中缀表达式字符串
public static List<String> getInffixExpressionList(String inffixExpression){
//定义一个list,存储中缀表达式内容
List<String> ls = new ArrayList<String>();
int i = 0;//指针用于遍历
String str;//用于对多位字符串进行拼接
char c;//便利到的每一个字符
do {
//非字符串直接介入
if((c=inffixExpression.charAt(i))<48 ||(c=inffixExpression.charAt(i))>57) {
ls.add(c+"");
i++;
}else {//数字考虑多位数
str="";
while(i<inffixExpression.length() && ((c=inffixExpression.charAt(i))>=48 && (c=inffixExpression.charAt(i))<=57)) {
str +=c;
i++;
}
ls.add(str);
}
} while (i<inffixExpression.length());
return ls;
}
}
- 其中获取优先级代码方法如下
class OperationPrioty {
private static int ADD = 1;
private static int SUB = 1;
private static int MUL = 1;
private static int DIV = 1;
public static int getPrioty(String operation) {
int result = 0;
switch (operation) {
case "+":
result = ADD;
break;
case "-":
result = SUB;
break;
case "*":
result = MUL;
break;
case "/":
result = DIV;
break;
default:
System.out.println("不存在该运算符");
break;
}
return result;
}
}
- 上述代码完成了将中缀表达式转为数组,再转为后缀表达式数组。
- 下面给出计算后缀表达式数组的代码。
public static int calculate(List<String> ls) {
Stack<String> stack = new Stack<String>();
//遍历ls
for(String item:ls) {
//使用正则表达式
if(item.matches("\\d+")) {//匹配多位数
stack.push(item);
}else {
//pop两个数,运算载入站
int num2 = Integer.parseInt(stack.pop());
int num1 = Integer.parseInt(stack.pop());
int res = 0;
if(item.equals("+")) {
res = num1 +num2;
}else if(item.equals("-")) {
res= num1 - num2;
}else if(item.equals("*")) {
res = num1 * num2;
}else if(item.equals("/")) {
res = num1 / num2;
}else {
throw new RuntimeException("运算符有误");
}
stack.push(""+res);
}
}
return Integer.parseInt(stack.pop());
}
计算结果
[3, 4, +, 5, *, 6, -]
29
前缀表达式[1, +, (, (, 2, +, 3, ), *, 4, ), -, 5]
不存在该运算符
不存在该运算符
后缀表达式[1, 2, 3, +, 4, *, +, 5, -]
计算结果16