具体步骤
-
初始化两个栈:运算符栈s1和储存中间结果的栈s2
在实际过程中,s2没有涉及到出栈操作,所以可以直接使用list代替(这样方便逆序); -
从左到又扫描中缀表达式;
-
遇到操作数时,将其压如s2;
-
遇到运算符时,比较其与s1栈顶运算符的优先级:
4.1. 如果s1为空,或栈顶运算符为左括号"(",则直接将此运算符入栈;
4.2. 否则,若优先级比栈顶运算符的高,也将运算符压入s1中;
4.3. 否则,将s1栈顶的运算符弹出并压入到s2中,再次转到4.1与s1中新栈顶运算符比较;
-
遇到括号时:
5.1. 如果是"(",直接压入s1;
5.2. 如果是")",则一次弹出s1的栈顶元素,并压入s2,直到遇上"("为止,此时将这一对括号丢弃
-
重复2到5,直到表达式到达最右边
-
将s1中剩余的运算符依次弹出并压入s2
-
依次弹出s2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式.
代码实现
public class infixToSuffix {
public static void main(String[] args) {
//定义一个中缀表达式
String expression = "1+((2+3)*4)-5";
//先将中缀表达式转换成list,方便操作
List<String> infixList = inFixToList(expression);
System.out.println("中缀表达式list = "+infixList);
//将中缀表达式转换成后缀表达式
List<String> suffixList = infixToSuffixList(infixList);
System.out.println("后缀表达式list = "+suffixList);
}
/**
* 将中缀表达式转换成后缀表达式
* @param infixList 中缀表达式的list
* @return
*/
private static List<String> infixToSuffixList(List<String> infixList) {
//初始化一个栈,存放符号
Stack<String> stack = new Stack();
//初始化一个数组存放结果(分析使用的栈,因为没有出栈操作,所以不需要使用栈实现,直接用list更加方便)
List<String> suffixList = new ArrayList<>();
for (String s : infixList) {
//如果是数字,直接添加到结果list中
if (s.matches("\d+")){
suffixList.add(s);
}else if (s.equals("(")){ //如果是"(" 直接入符号栈
stack.push(s);
}else if (s.equals(")")){ //如果是")",则需要把符号栈中的符号出栈,把运算符添加到结果list中,直到匹配到"(",且"("出栈
while (!stack.peek().equals("(")){
suffixList.add(stack.pop());
}
//出栈"("
stack.pop();
}else { //如果是运算符,则需要比较优先级
//栈中运算符的优先级大于等于当前的,则出栈,且添加到结果list中
while (stack.size() !=0 && Priority.getPriority(s)<=Priority.getPriority(stack.peek())){
suffixList.add(stack.pop());
}
//栈中运算符的优先级小于当前的,入栈
stack.push(s);
}
}
//将栈中剩余的运算符取出,添加到结果list中
while (stack.size()!=0){
suffixList.add(stack.pop());
}
return suffixList;
}
/**
* 将中缀表达式转换成list
* @param expression
* @return
*/
private static List<String> inFixToList(String expression) {
List<String> infixList = new ArrayList<>();
int index = 0; //遍历字符串指针
String str = ""; //合并多位数
char ch;
//数字的ASCII 49~57
while (index < expression.length()){
ch = expression.charAt(index);
//字符不是数字
if (ch < 49 || ch > 57){
infixList.add(""+ch);
index ++;
}else {
//是数字,判断是否为多位数,是就拼接
//拼接之前,先置空
str = "";
while (index<expression.length() && (ch=expression.charAt(index))>=49 &&
(ch=expression.charAt(index))<=57){
str+=ch;
index ++;
}
infixList.add(str);
}
}
return infixList;
}
}
class Priority{
//这里只考虑加减乘除
private static final int ADD = 1;
private static final int SUB = 1;
private static final int MUL = 2;
private static final int DIV = 2;
/**
*
* @param op 操作符
* @return返回优先级
*/
public static int getPriority(String op){
int res = 0;
switch (op){
case "+":
res = ADD;
break;
case "-":
res = SUB;
break;
case "*":
res = MUL;
break;
case "/":
res = DIV;
break;
default:
break;
}
return res;
}
}