中缀表达式:人们通常使用的式子,按照运算符的优先进行计算,例如:3*(5+7)-6,但中缀表达式不利于计算机的处理,便出现了后缀表达式。
后缀表达式:运算符位于操作数之后,例如 3*(5+7)-6,对应的后缀表达式为 3 5 7 + * 6 -
- 将中缀表达式转为对应的List
public static List<String> toInfixExpressionList(String s){
//定义一个List,存放表达式
List<String> ls = new ArrayList<String>();
int i=0;//指针用于遍历中缀表达式字符串
String str;//对多位数的拼接
char c;//遍历的每一个字符存放在c
do{
//如果c是一个非数字,就要加入到ls
if ((c=s.charAt(i))<48||(c=s.charAt(i))>57){
ls.add(""+c);
i++;
}else {//如果是一个数,需要考虑是否为多位数
str="";
while (i<s.length()&&(c=s.charAt(i))>=48&&(c=s.charAt(i))<=57){
str+=c;
i++;
}
ls.add(str);
}
}while (i<s.length());
return ls;
}
- 将得到的中缀表达式对应的List——>后缀表达式对应的List
public static List<String> parseSuffixExpression(List<String> ls){
//定义一个符号栈,一个list存储中间结果
Stack<String> s1 = new Stack<String>();
List<String> s2 = new ArrayList<String>();
//遍历s1
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&&Operation.getvalue(s1.peek())>=Operation.getvalue(item)){
s2.add(s1.pop());
}
//将item压入栈中
s1.push(item);
}
}
//将s1剩余的运算符依次弹出并加入s2
while(s1.size()!=0){
s2.add(s1.pop());
}
return s2;
}
- 完成对逆波兰表达式的运算
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);//将int转为字符串,也可以使用String.value(res)/res+""
}
}
return Integer.parseInt(stack.pop());
}
}
- 返回运算符优先级类
class Operation{
private static int ADD=1;
private static int SUB=1;
private static int MUL=2;
private static int DIV=2;
public static int getvalue(String operation){
int res = 0;
switch (operation){
case "+":
res = ADD;break;
case "-":
res = SUB;break;
case "*":
res = MUL;break;
case "/":
res = DIV;break;
default:
break;
}
return res;
}
}
- 主方法
public static void main(String[] args) {
String s = "5+(2+3)*4-5";
List<String> infixElist = toInfixExpressionList(s);
List<String> suffixEList = parseSuffixExpression(infixElist);
System.out.println(s+"后缀表达式为"+suffixEList);
int res = calculate(suffixEList);
System.out.println("逆波兰表达式"+suffixEList+"的结果是:"+res);
}
- 输出结果
5+(2+3)*4-5后缀表达式为[5, 2, 3, +, 4, *, +, 5, -]
逆波兰表达式[5, 2, 3, +, 4, *, +, 5, -]的结果是:20