计算后缀表达式我们首先要将中缀表达式转换成后缀表达式,后缀表达式也叫逆波兰表达式,即将运算符写在操作数之后,如:
1. 将中缀表达式转换成后缀表达式:
//将中缀表达式转换成后缀表达式
public class InfixToSuffix {
public static void main(String[] args) {
String expression = "(10+20/2*3)/2+8";
expression = infixToSuffix(expression);
System.out.println(expression);
}
//将中缀表达式转换成后缀表达式
public static String infixToSuffix(String expression) {
ArrayStack<String> operatorStack = new ArrayStack<>(); //字符栈 只存放字符
ArrayList<String> suffixList = new ArrayList<>();
expression = insertBlanks(expression); //按照指定格式格式化字符串
String[] tokens = expression.split(" "); //按照“ ”分割字符串
for(String token : tokens){
if(token == null){
continue;
}
if(isOperator(token)){
/*
1.栈为空时
2.栈顶元素时 “(”
3.当栈顶元素是操作符 且栈顶操作符的优先级 小于 当前token
如果满足以上三个条件中的一个 就将当前字符token添加到字符栈operatorStack中
如果栈顶元素操作符的优先级 大于等于 当前token 就将字符栈中的栈顶字符弹出并添加到列表suffixList中
*/
while (true){
if(operatorStack.isEmpty() || operatorStack.peek().equals("(") ||
priority(operatorStack.peek()) < priority(token)){
operatorStack.push(token);
break;
}
suffixList.add(operatorStack.pop());
}
}else if(token.equals("(")){ //如果当前字符是"("就直接将字符压入字符栈中
operatorStack.push(token);
}else if(token.equals(")")){ //如果当前字符是")" 就将字符栈中的所有栈顶元素都依次弹出并添加到列表suffixList中 直到栈顶字符是"("
while (!operatorStack.peek().equals("(")){
suffixList.add(operatorStack.pop());
}
operatorStack.pop();
}else if(isNumber(token)){ //如果当前字符是数字字符 就直接将数字字符添加到列表suffixList中
suffixList.add(token);
}
}
//遍历完字符串后 字符栈中还会有操作符
//将字符栈中剩余的操作符全都依次弹出并添加到suffixList中
while (!operatorStack.isEmpty()){
suffixList.add(operatorStack.pop());
}
StringBuilder str = new StringBuilder();
for(int i = 0; i < suffixList.size(); i++){
str.append(suffixList.get(i));
str.append(' ');
}
return str.toString();
}
//判断操作符的优先级
//"-" "+"的优先级设为0 "*" "/"的优先级设为1
private static int priority(String token) {
if(token.equals("+") || token.equals("-")){
return 0;
}else if(token.equals("*") || token.equals("/")){
return 1;
}
return -1;
}
//判断当前token字符是否是操作符
private static boolean isOperator(String token) {
return token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/");
}
//判断当前token字符是否是数字字符
private static boolean isNumber(String token) {
return token.matches("\\d+"); //正则表达式 \d表示匹配数字 +表示匹配多个
}
//对原表达式进行格式化处理 给所有的非数字字符两边添加空格
//是表达式变为“ ( 10 + 20 / 2 * 3 ) / 2 + 8”
private static String insertBlanks(String express) {
StringBuilder newExpress = new StringBuilder();
for(int i = 0; i < express.length(); i++){
char c = express.charAt(i);
if(c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/'){
newExpress.append(' ');
newExpress.append(c);
newExpress.append(' ');
}else{
newExpress.append(c);
}
}
return newExpress.toString();
}
}
2. 将中缀表达式转换成后缀表达式之后,就可以计算后缀表达式啦
//计算后缀表达式
public class SuffixCalculator {
public static void main(String[] args) {
String expression = "(10+20/2*3)/2+8";
String suffixExpression = InfixToSuffix.infixToSuffix(expression);
int result = evaluateExpression(suffixExpression);
System.out.println(result);
}
//计算后缀表达式
//只需要一个数字栈 遍历后缀表达式 如果遇到操作符 直接从数字栈中弹出两个数字进行运算
//最后将运算结果压入数字栈即可
private static int evaluateExpression(String suffixExpression) {
String[] tokens = suffixExpression.split(" ");
ArrayStack<Integer> numberStack = new ArrayStack<>();
for(String token : tokens){
if(token == null){
continue;
}else if(isNumber(token)){
numberStack.push(Integer.parseInt(token));
}else{
processAnOperator(numberStack, token);
}
}
return numberStack.pop();
}
//判断字符串token是否是数字字符串
private static boolean isNumber(String token){
return token.matches("\\d+"); //正则表达式 \d表示匹配数字 +表示匹配多个
}
//按照指定格式格式化字符串
private static void processAnOperator(ArrayStack<Integer> numberStack, String token) {
int num1 = numberStack.pop();
int num2 = numberStack.pop();
if(token.equals("+")){
numberStack.push(num2 + num1);
}else if(token.equals("-")){
numberStack.push(num2 - num1);
}else if(token.equals("*")){
numberStack.push(num2 * num1);
}else if(token.equals("/")){
numberStack.push(num2 / num1);
}
}
}
中缀转后缀表达式
本文介绍如何将中缀表达式转换为后缀表达式(逆波兰表达式),并通过一个具体的例子展示了整个转换过程及计算步骤。文章还提供了一个Java实现的方法来完成这一转换,并解释了计算后缀表达式的算法。
735

被折叠的 条评论
为什么被折叠?



