中缀表达式转后缀表达式
后缀表达式
后缀表达式又称逆波兰表达式,明显的特点是:逆波兰表达式中没有括号,计算时将操作符之前的第一个数作为右操作数,第二个数作为左操作数,进行计算,得到的值继续放入逆波兰表达式中。 但日常生活中我们总是习惯于写中缀表达式,所以需要先将中缀表达式转为后缀表达式。
规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。
简单图解后缀表达式
opStack用于存储操作符,suffixList用于存储后缀表达式字符。将操作符按照操作顺序及操作符优先级写入操作符栈,然后将整个表达式按后缀表达式特点依次存入线性表中
代码实现
public String infixToSuffix(String infixExpression){
//定义一个操作符栈
ArrayStack<String> opStack = new ArrayStack<>();
//定义一个存后缀字符的线性表
ArrayList<String> suffixList = new ArrayList<>();
//格式化表达式
infixExpression = insertBlanks(infixEXpression);
String[] tokens = infixExpression.split(" ");
System.out.println(Arrays.toString(tokens));
for(String token : tokens){
if(token.length() == 0){
continue;
}
if(isOperator(token)){ //如果是操作符
while(true){
//栈空 或 栈顶是( 直接进; 当前操作符的优先级 > 栈顶操作符的优先级 直接进
if(opStack.isEmpty() || "(".equals(opStack.peek()) || priority(token) > poiority(opStack.peek())){
opStack.push(token);
break;
}
//如果栈不为空 且 栈顶不是( 且栈顶操作符优先级 >= 当前操作符优先级
suffixList.add(opStack.pop());
}
}else if (isNumber(token)){ //如果是数字
suffixList.add(token);
}else if ("(".equals(token)){ //如果是“(”
opStack.push(token);
}else if (")".equals(token)){ //如果是“)”
while (true){
if ("(".equals(opStack.peek())){
opStack.pop();
break;
}else{
suffixList.add(opStack.pop());
}
}
}else {
throw new IllegalArgumentException("wrong identify"+ token);
}
}while (!opStack.isEmpty()){
suffixList.add(opStack.pop());
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < suffixList.size; i++) {
sb.append(suffixList.get(i)+" ");
}
return sb.toString();
}
private int priority(Sting token){
if("*".equals(token) || "/".equals(tokens)){
return 1;
}else if("+".equals(token) || "-".equals(tokens)){
return 0;
}else{
return -1;
}
}
private boolean isOperator(String token){
return "+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token);
}
private boolean isNumber(String token){
return token.matches("\\d+"); // \\d+匹配的是表示多个数字
}
private String insertBlanks(String expression){
StringBuilder sb = new StringBuilder();
//遍历表达式
for(int i = 0; i < expression.length(); i++){
char c = expression.charAt(i);
//如果是符号,则在符号前后增加空格
if(c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/'){
sb.append(" ");
sb.append(c);
sb.append(" ");
}else { //如果遇到数字 则原封不动添加在sb
sb.append(c);
}
}
return sb.toString();
}
}
运行结果: