【Java】中缀表达式转后缀表达式和后缀表达式四则运算求值

过程概述

中缀表达式转后缀表达式过程概述:从左到右遍历中缀表达式,若是数字就输出成为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级不高于栈顶符号(乘除取模优先加减)则栈顶元素依次出栈并输出,并将当前符号进栈,一直到输出后缀表达式为止。

后缀表达式四则运算求值过程概述:从左到右遍历后缀表达式,若是数字就进栈,若是符号,将处于栈顶两个数字出栈,用该符号运算,运算结果进栈,最后栈中剩下的就是最终结果。

代码实现

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 用List集合来装后缀表达式,可以进行多位数的四则运算
 */
public class CalculatorPlus {
    public static List infixToPostfix(String infixExpression){
        Stack operatorStack=new Stack<>();
        List postfixExpression=new ArrayList<>();
        for(int i=0;i postfixExpression){
        Stack stack=new Stack<>();//放用来计算的数字
        //从左至右遍历后缀表达式
        for(String s:postfixExpression){
            //如果是数值
            if(s.charAt(0)>=48&&s.charAt(0)<=57){
                stack.push(Integer.valueOf(s));
            }else {
                //如果是运算符
                switch (s){
                    case "+":
                        stack.push(stack.pop()+stack.pop());
                        break;
                    case "-":
                        //pop1是被减数,pop2是减数,先pop出来的是减数
                        /*
                        2    -  1    =  1
                        被减数  减数   差           /和%类似
                         */

                        Integer pop2 = stack.pop();
                        Integer pop1 = stack.pop();
                        stack.push(pop1-pop2);
                        break;
                    case "*":
                        stack.push(stack.pop()*stack.pop());
                        break;
                    case "/":
                        Integer pop4 = stack.pop();
                        Integer pop3 = stack.pop();
                        stack.push(pop3/pop4);
                        break;
                    case "%":
                        Integer pop6 = stack.pop();
                        Integer pop5 = stack.pop();
                        stack.push(pop5%pop6);
                        break;
                    default:
                        throw new IllegalArgumentException("无效的运算符:"+s);
                }
            }
        }
        // 栈顶元素即为最终结果
        return stack.pop();
    }
    //在中缀转后缀时要判断符号优先级
    private static int getPrecedence(char operator) {
        switch (operator) {
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
            case '%':
                return 2;
            default:
                return 0;
        }
    }
}

tips

 栈在两个地方的作用:

 中缀表达式转后缀表达式时用栈存放运算符,后缀表达式四则运算求值时用栈存放操作数

另外

第一次实现该算法的时候,没有考虑到多位数,只能实现一位数的四则运算,但对理解原理也有帮助,如果上面的用List集合看不明白的话可以先理解理解下面的再去看上面的:

import java.util.Stack;

/**
 * 只能实现一位数的四则运算
 */
public class Calculator {
    //中缀表达式转后缀表达式
    public static String infixToPostfix(String infixExpression){
        StringBuilder postfixExpression=new StringBuilder();
        Stack operatorStack=new Stack<>();   //用来存放运算符
        //从左至右依次遍历中缀表达式
        for(char c:infixExpression.toCharArray()){
            //如果是数字
            if(Character.isDigit(c)){
                postfixExpression.append(c);
            //如果是(
            }else if(c=='('){
                operatorStack.push(c);
            //如果是)
            }else if(c==')'){
                //一直pop,直到匹配到(
                while (!operatorStack.empty()&&operatorStack.peek()!='('){
                    //将过程中pop出来的运算符追加到后缀表达式中
                    postfixExpression.append(operatorStack.pop());
                }
                //如果是+-*/%
            }else {
                //将优先级<=当前运算符优先级的运算符pop出来,追加到后缀表达式中
                while (!operatorStack.empty()&&getPrecedence(c)<=getPrecedence(operatorStack.peek())){
                    postfixExpression.append(operatorStack.pop());
                }
                //将当前运算符进栈
                operatorStack.push(c);
            }
        }
        //将栈中剩余的运算符依次pop出来追加到结果中
        while (!operatorStack.empty()){
            postfixExpression.append(operatorStack.pop());
        }
        return postfixExpression.toString();
    }

    //后缀表达式求值
    public static int evaluatePostfix(String postfixExpression){
        Stack stack=new Stack<>();//放用来计算的数字
        //从左至右遍历后缀表达式
        for(int i=0;i

你可能感兴趣的:(数据结构与算法,java,数据结构,算法)