如果不知道什么是前缀、中缀、后缀表达式的请参考此博客
https://blog.csdn.net/Antineutrino/article/details/6763722
1、将中缀表达式转换成列表,方便运算
/**
* 将表达式放进list
* @param expression
* @return 中缀表达式列表
*/
public List<String> parseInfixToList(String expression){
List<String> list = new ArrayList<>();
int index = 0;
char c ;
String str = "";
do {
c=expression.charAt(index);
//如果是非数字,直接放进list
if ( c<48 || c>57){
list.add(""+c);
index++;
}
//如果是数字,判断是否多位数
else {
//字符串拼接
str = "";
while (index < expression.length() && expression.charAt(index) >= 48 && expression.charAt(index) <= 57){
str +=c;
index++;
}
list.add(str);
}
}while (index < expression.length());
return list;
}
2、将中缀表达式转换成后缀表达式(重点)
/**
* 将中缀表达式放进list,再将list转化为后缀表达式的list
* @param list 中缀表达式的list
* @return
*/
public List<String> parseSuffixExpressionList(List<String> list){
//工具1存放运算符
Stack<String> operaStack = new Stack<>();
//存储中间结果,为了简化操作,用list,list中的顺序就是逆波兰表达式
List<String> resList = new ArrayList<>();
//遍历list
for (String item:list){
//如果是数字,push to s2
if (item.matches("\\d+")){
resList.add(item);
}
else if (item.equals("(")){
operaStack.push(item);
}
//when meet ")",则依次弹出s1栈顶的运算符,并且压入s2,知道遇到“(”为止
else if (item.equals(")")){
while (!operaStack.peek().equals("(")){
resList.add(operaStack.pop());
}
//此时将这一对括号丢弃
operaStack.pop();
}
//when meet operator ,compare with the operator s1[top]
// else if cur operator's priority 》s1[top] ,push it to s1;
// else pop operator from s1[top] and push it to s2,than turn to if
else {
while (operaStack.size()>0 && Operator.getPriority(item) <= Operator.getPriority(operaStack.peek())){
resList.add(operaStack.pop());
}
operaStack.push(item);
}
}
//将s1中的剩余运算符依次弹出并且加入到list
while (operaStack.size() > 0){
resList.add(operaStack.pop());
}
return resList;
}
3、计算结果
/**
* 计算结果
* @param itemList 后缀表达式
* @return 最后的运算结果
*/
public static int calculate(List<String> itemList){
//工具栈
Stack<String> stack = new Stack<>();
for (String elem:itemList){
//如果是数字,则进栈
if (elem.matches("\\d+")){
stack.push(elem);
}
//如果是符号则出栈两个数进行运算
else{
int num1 = Integer.parseInt(stack.pop());
int num2 = Integer.parseInt(stack.pop());
//暂存结果
int res = 0;
if (elem.equals("+")){
res = num1+num2;
}
else if (elem.equals("-")){
res = num2-num1;
}
else if (elem.equals("*")){
res = num1*num2;
}
else if (elem.equals("/")){
res = num2/num1;
}
else {
throw new RuntimeException("运算符有误");
}
//将res入栈
stack.push(String.valueOf(res));
}
}
//遍历结束,留在栈中的就是最后结果
return Integer.parseInt(stack.pop());
}
除此以外,我们还需要一个自定义运算符优先级的类
class Operator{
/**
* 优先级
*/
private static int PLUS = 1;
private static int SUB = 1;
private static int MUL = 2;
private static int DIV = 2;
public static int getPriority(String val){
int priority = 0;
switch (val){
case "+":
priority = 1;
break;
case "-":
priority = 1;
break;
case "*":
priority = 2;
break;
case "/":
priority = 2;
break;
default:
break;
}
return priority;
}
}