美文网首页
Java后缀表达式实现表达式求值

Java后缀表达式实现表达式求值

作者: 代江波 | 来源:发表于2020-11-17 14:46 被阅读0次
    package com.djb.calculatdemo;
    
    import java.util.ArrayList;
    import java.util.Stack;
    
    import javax.management.RuntimeErrorException;
    
    public class CalculatTest {
        public static void main(String[] args) {
            ArrayList<String> suffixfxpression = getSuffixfxpression("10.5+((2+3)*4)-5/2");
            double calculate = calculate(suffixfxpression);
            System.out.println(calculate);
        }
    
        /**
         * 将中缀表达式字符串转成后缀表达式数组
         * @param str 传入的中缀表达式字符串
         * @return 后缀表达式数组
         */
        private static ArrayList<String> getSuffixfxpression(String str){
            //保存运算符号的栈
            Stack<String> signStack = new Stack<String>();
            //保存后缀表达式的数组
            ArrayList<String> numList = new ArrayList<String>();
            //保存当前遍历到的数字
            StringBuffer curNum = new StringBuffer();
    
            for (int i = 0; i < str.length(); i++) {
                //当前遍历的字符
                char ch = str.charAt(i);
                if (ch >= 48 && ch <= 57 || ch == '.') {//遍历到是数字
                    curNum.append(ch);
                    //获取一个完整的数字
                    int j = i + 1;
                    while (true) {
                        if (j == str.length()) {
                            break;
                        }
                        
                        if (str.charAt(j) >= 48 && str.charAt(j) <= 57 || str.charAt(j) == '.') {
                            curNum.append(str.charAt(j));
                        }else {
                            break;
                        }
                        
                        j ++;
                    }
                    
                    //将获取到的完整数字放入数组中
                    numList.add(curNum.toString());
                    //清空当前拼接的数字
                    curNum.delete(0, curNum.length());
                    i = j - 1;
                    
                }else if (ch == '(') {//遍历到左括号直接入符号栈
                    signStack.push(String.valueOf(ch));
                }else if (ch == ')') {//遍历到右括号,将符号栈的符号依次加入到数组数组中,知道碰到左括号,再将左括号出栈
                    while (!signStack.peek().equals("(")) {
                        numList.add(signStack.pop());
                    }
                    signStack.pop();
                }else {//遍历到运算符号时,如果当前运算符号优先级低于符号栈顶的优先级,将符号栈栈顶出栈加入到数字数字中,知道当前符号高于栈顶的优先级
                    while (signStack.size() > 0 && getSymbolGread(signStack.peek()) >= getSymbolGread(String.valueOf(ch))) {
                        numList.add(signStack.pop());
                    }
                    //最后将当前符号入栈
                    signStack.push(String.valueOf(ch));
                }
                
            }
            //将符号栈的数据依次出栈加入到数字数组中
            while (signStack.size() > 0) {
                numList.add(signStack.pop());
                
            }
            return numList;
        }
        
        /**
         * 根据后缀表达式计算结果
         * @param array 后缀表达式的数组
         */
        private static double calculate(ArrayList<String> array) {
            Stack<String> numStack = new Stack<String>();
            //正序遍历后缀表达式数组
            for (String item : array) {
                if (isSymbol(item)) {//遍历到运算符,顺序在栈中取出两个数,然后逆向让两个数运算,将运算的结果入栈
                    double result = 0;
                    double num1 = Double.parseDouble(numStack.pop());
                    double num2 = Double.parseDouble(numStack.pop());
                    if (item.equals("+")) {
                        result = num2 + num1;
                    }else if (item.equals("-")) {
                        result = num2 - num1;
                    }else if (item.equals("*")) {
                        result = num2 * num1;
                    }else if (item.equals("/")) {
                        result = num2 / num1;
                    }else {
                        throw new RuntimeErrorException(null, "非法的运算符");
                    }
                    numStack.push(String.valueOf(result));
                }else {//遍历到数字,直接入栈
                    numStack.push(item);
                }
            }
            //最后出栈的就是计算的结果
            return Double.parseDouble(numStack.pop());
        }
        
        /**
         * 获取运算符号的优先级
         * @param symbol 传入的运算符号
         */
        private static int getSymbolGread(String symbol){
            int gread = 0;
            switch (symbol) {
            case "+":
            case "-":
                gread = 1;
                break;
            case "*":
            case "/":
                gread = 2;
            default:
                break;
            }
            return gread;
        }
        
        /**
         * 判断传入的字符串是否为运算符号
         * @param str 传入的字符串
         */
        private static boolean isSymbol(String str) {
            return str.equals("+") || str.equals("-") || str.equals("*") || str.equals("/");
        }
        
    }
    
    
    
    

    相关文章

      网友评论

          本文标题:Java后缀表达式实现表达式求值

          本文链接:https://www.haomeiwen.com/subject/zpbxiktx.html