Java代码实现表达式计算(带括号)

思路分析:

  1. 如果是数字,直接放入数栈
  2. 如果是操作符
    2.1 判断符号栈是否为空,如果为空直接放入符号栈
    2.2 如果不为空,判断当前符号
    2.2.1 是否为括号,如果是"(",直接放入符号栈;如果是")",数栈弹出两个数,符号栈弹出符号继续运算,结果入栈,直到弹出的符号为"("
    2.2.2 是否为操作符,如果是则判断和栈顶符号的优先级,小于等于则数栈弹出两个数,符号栈弹出符号继续运算,结果入栈,再把扫描的当前运算符入栈
    若大于直接入栈。
  3. 清空数栈和符号栈,依次弹出进行运算,每次运算结果入栈
  4. 代码实现:
package com.cwnu.stack;

import java.util.Stack;

/*
 * 带有括号的表达式计算
 * */
/*
思路分析,对表达式继续扫描
    1. 如果是数字,直接放入数栈
    2. 如果是操作符
        2.1 判断符号栈是否为空,如果为空直接放入符号栈
        2.2 如果不为空,判断当前符号
            2.2.1 是否为括号,如果是"(",直接放入符号栈;如果是")",数栈弹出两个数,符号栈弹出符号继续运算,结果入栈,直到弹出的符号为"("
            2.2.2 是否为操作符,如果是则判断和栈顶符号的优先级,小于等于则数栈弹出两个数,符号栈弹出符号继续运算,结果入栈,再把扫描的当前运算符入栈
                        若大于直接入栈。
    3.清空数栈和符号栈,依次弹出进行运算,每次运算结果入栈
*/
public class CalculatorBrackets {
    public static void main(String[] args) {
        //声明两个栈(数栈,符号栈)
        Stack<Integer> numberStack = new Stack<>();
        Stack<String> operStack = new Stack<>();
        //声明字符串
        String express = "3 * ( ( 2 + 5 ) + 8 / ( 2 * 2 + 2 * 2 ) )";
        //将字符串转化为数组
        String[] strings = express.split(" ");
        //遍历数组字符串
        for (String itme : strings) {
            //首先判断是否为数字
            if (!isOper(itme)) {//表示位数字,直接入数栈
                System.out.println(itme);
                numberStack.push(Integer.valueOf(itme));
            } else {
                //判断栈是否为空,为空直接入栈
                if (operStack.isEmpty()) {
                    operStack.push(itme);
                } else {//不为空
                    if (itme.equals("(") || itme.equals(")")){//判断是否为括号
                        if(itme.equals("(")){
                            operStack.push(itme);
                        }else {
                            while (true){
                                String oper = operStack.pop();
                                if (oper.equals("(")){
                                    break;
                                }
                                int num1 = numberStack.pop();
                                int num2 = numberStack.pop();
                                numberStack.push(calculation(num1,num2,oper));
                            }
                        }
                    }else {
                        if (priority(itme) > priority(operStack.peek())) {
                            operStack.push(itme);
                        }else if (priority(itme) <= priority(operStack.peek())){
                            System.out.println(operStack.peek());
                            int num1 = numberStack.pop();
                            int num2 = numberStack.pop();
                            String oper = operStack.pop();
                            numberStack.push(calculation(num1,num2,oper));
                            operStack.push(itme);//当前符号栈进栈
                        }
                    }
                }
            }
        }
        int res;
        while (true) {
            if (numberStack.size() == 1) {
                res = numberStack.pop();
                break;
            }
            int num1 = numberStack.pop();
            int num2 = numberStack.pop();
            String oper = operStack.pop();
            numberStack.push(calculation(num1, num2, oper));
        }
        System.out.println("表达式计算结果为:" + res);
    }

    //判断是否为运算符
    public static boolean isOper(String e) {
        if (e.equals("*")){
            return true;
        }else if (e.equals("/")){
            return true;
        }else if (e.equals("+")){
            return true;
        }else if (e.equals("-")){
            return true;
        }else if (e.equals("(")){
            return true;
        }else if (e.equals(")")){
            return true;
        }else{
            return false;
        }
    }

    //计算
    public static int calculation(int num1, int num2, String e) {
        int res = 0;
        switch (e) {
            case "+":
                res = num1 + num2;
                break;
            case "*":
                res = num1 * num2;
                break;
            case "-":
                res = num2 - num1;
                break;
            case "/":
                res = num2 / num1;
                break;
            default:
                break;
        }
        return res;
    }

    //符号的优先级
    public static int priority(String e) {
        if (e.equals("*") || e.equals("/")) {
            return 1;
        } else if (e.equals("+") || e.equals("-")) {
            return 0;
        } else {
            return -1;
        }
    }
}