思路分析
- 两个栈,s1存运算符,s2存中间结果
- 从左到右扫描:
- 遇到数,压s2
- 遇到运算符:
- 若s1为空,或者s1栈顶为(,则直接压入
- 若优先级比栈顶的高,也压入
- 否则将s1栈顶的弹出,压到s2,再次与新栈顶比较
- 遇到括号
- 左括号,直接压入
- 有括号,弹出s1栈顶,压入s2,直到遇到(为止,此时左右括号废弃
- 将s1剩余的依次压入s2
- 依次弹出s2,s2的逆序就是后缀表达式!
但是,一般在实际操作中,并不是将s2设置为栈,因为栈的先进后出的存储数据原则,导致取逆序太麻烦,因此将s2设置为List类型结构,直接return s2即可获得后缀表达式(list)
package com.ran;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
public class Hello {
public static void main(String[] args) {
String biaodashi="1+((2+3)*4)-5";
System.out.println(bianli(biaodashi));
System.out.println(houzhui(bianli(biaodashi)));
}
public static List<String> houzhui(List<String> list){
//定义两个栈
Stack<String> s1 = new Stack<>();
//说明:因为s2这个栈在整个转换过程中没有pop操作,而且后面还需要逆序输出,因此比较麻烦,我们不用stack,直接使用List
List<String> s2=new ArrayList<String>();
//遍历list
for (String qq : list) {
//若果是一个数,就压入s2
if(qq.matches("\\d+")){
s2.add(qq);
}else if(qq.equals("(")){
s1.push(qq);
}else if(qq.equals(")")){
while (!s1.peek().equals("(")){
s2.add(s1.pop());
}
s1.pop(); //将这个小括号弹出 废弃
}else{
//当qq的优先级小于等于s1栈顶的运算符优先级时:将s1栈顶的运算符加入到s2中,再次与新栈顶运算符相比较
while (s1.size()!=0&& youxianji.dedaoyouxianji(s1.peek())>=youxianji.dedaoyouxianji(qq)){
s2.add(s1.pop());
}
//还需要将qq压入栈顶
s1.push(qq);
}
}
//将s1中剩余的运算符加入s2中
while (s1.size()!=0){
s2.add(s1.pop());
}
return s2; //因为是存放到list,因此按顺序输出就是对应的后缀list
}
//编写优先级的类
//返回对应的优先级数字
public static List<String> bianli(String biaodashi) {
List<String> list = new ArrayList<String>();
int i=0;
char c;
String str;
do {
if ((c = biaodashi.charAt(i)) < 48 || (c = biaodashi.charAt(i)) > 57) {
list.add("" + c);
i++;
} else {
str = "";
if ((c = biaodashi.charAt(i)) >= 48 && (c = biaodashi.charAt(i)) <= 57 && i < biaodashi.length()) {
str += c;
list.add(str);
i++;
}
}
}while (i<biaodashi.length());
return list;
}
}
class youxianji{
private static int jia=1;
private static int jian=1;
private static int cheng=1;
private static int chu=1;
public static int dedaoyouxianji(String qq){
int res=0;
switch (qq){
case "+":
res=jia;
break;
case "-":
res=jian;
break;
case "*":
res=cheng;
break;
case "/":
res=chu;
break;
default:
System.out.println("不存在该运算符");
break;
}
return res;
}
}
代码运行如下: