话不多说上例子:1+((2+3)*4)-5 => 1 2 3 + 4 * + 5 -
中缀表达式转后缀表达式思路分析:
1.首先需要两个栈 运算符栈 s1 和存储中间结果的栈 s2
2.从左至右扫描中缀表达式
2.1当前为操作数,将其压栈至S2
2.2当前为运算符
2.2.1如果S1为空或者栈顶运算符为左括号 “(” 则将此运算符直接入S1栈
2.2.2当前为运算符 “(” 左括号时,则直接压入S1
2.2.3当前为运算符 “)” 右括号时,则依次弹出S1栈顶的运算符,压入S2,直至遇到 “(” 左括号时为止 这时将这一对括号丢弃。
2.2.4当前运算符优先级比栈顶运算符优先级高,将运算符压入S1,否则将S1栈顶运算符弹出再压入S2中,后重复运算符逻辑 (2.2)
先放将中缀表达式字符串转换成list程序:
// 将字符串转换成list
public static List<String> getListString(String suffixExpression) {
String[] split = suffixExpression.split(" ");
List<String> list = new ArrayList<String>();
for (String str : split) {
list.add(str);
}
return list;
}
接下来需要一个返回运算符优先级的方法:
class Operation {
private static int ADD = 1;
private static int SUB = 1;
private static int MUL = 2;
private static int DIV = 2;
private static int OTH = 0;
public static int getPow(String oper) {
int res = 0;
switch (oper) {
case "+":
res = ADD;
break;
case "-":
res = SUB;
break;
case "*":
res = MUL;
break;
case "/":
res = DIV;
break;
default:
res = OTH;
break;
}
return res;
}
}
最后是转换方法,值得注意的是因为S2栈本来是存储过程值最后需要将栈内容倒序输出才是后缀表达式所以在方法中,就不再定义S2栈,直接用list做返回值:
// 中缀表达式转后缀表达式
public static List<String> parseSuffixExpressionList(List<String> list) {
// 定义一个栈用来存放符号
Stack<String> s = new Stack<String>();
// 存放最后的后缀表达式
List<String> l = new ArrayList<String>();
for (String item : list) {
// 利用正则判断当前字符串是否为数字
if (item.matches("\\d+")) {
l.add(item);
} else {
if ("(".equals(item)) {
s.push(item);
} else if (")".equals(item)) {
while (!"(".equals(s.peek())) {
l.add(s.pop());
}
// 把 栈中剩余的 ( 出栈
s.pop();
} else {
while (s.size() != 0 && Operation.getPow(item) <= Operation.getPow(s.peek())) {
// 判断 运算符优先级
l.add(s.pop());
}
s.push(item);
}
}
System.out.print("s1栈:"+l);
System.out.println("s2栈:"+s+" ");
}
while(s.size()!=0) {
l.add(s.pop());
}
return l;
}
最后程序运行的结果:
最后的结果的运算可以参考我上一篇后缀表达式计算器求值。