Seemyeyes7 2019-10-14 15:45 采纳率: 50%
浏览 664
已采纳

JAVA实现算术表达式的求值

补充中间有补充代码提示的地方就好能附上说明更好

package eval;

public class Util {

    /**
     * 计算表达式 express 的值
     * 如: eval("3+5*3") 返回 18
     */
    public static double eval(String express) {
        char[] chars = express.toCharArray();

        // .... 补充代码 ....

        return 0;
    }

    /**
     * 求 a 和 b 进行算术运算的结果。 
     * 例如:calculate(3, 5, '+') 返回  8
     */
    private static double calculate(double a, double b, char op) {
        switch (op) {
        case '+':
            return a + b; 
        case '-':
            return a - b; 
        case '*':
            return a * b; 
        case '/':
            return a / b; 
        default:
            throw new RuntimeException("不支持此运算"); 
        }
    }
}

  • 写回答

4条回答 默认 最新

  • 关注
    import java.util.Collections;
    import java.util.Stack;
    
    public class Calculator {
        private Stack<String> postfixStack  = new Stack<String>();//后缀式栈
        private Stack<Character> opStack  = new Stack<Character>();//运算符栈
        private int [] operatPriority  = new int[] {0,3,2,1,-1,1,0,2};//运用运算符ASCII码-40做索引的运算符优先级
        public static void main(String[] args) {
            System.out.println(5+12*(3+5)/7.0);
            Calculator cal  = new Calculator();
            String s = "5+12*(3+5)/7";
            double result  = cal.calculate(s);
            System.out.println(result);
        }
    
        /**
         * 按照给定的表达式计算
         * @param expression 要计算的表达式例如:5+12*(3+5)/7
         * @return
         */
        public double calculate(String expression) {
            Stack<String> resultStack  = new Stack<String>();
            prepare(expression);
            Collections.reverse(postfixStack);//将后缀式栈反转
            String firstValue  ,secondValue,currentValue;//参与计算的第一个值,第二个值和算术运算符
            while(!postfixStack.isEmpty()) {
                currentValue  = postfixStack.pop();
                if(!isOperator(currentValue.charAt(0))) {//如果不是运算符则存入操作数栈中
                    resultStack.push(currentValue);
                } else {//如果是运算符则从操作数栈中取两个值和该数值一起参与运算
                     secondValue  = resultStack.pop();
                     firstValue  = resultStack.pop();
                     String tempResult  = calculate(firstValue, secondValue, currentValue.charAt(0));
                     resultStack.push(tempResult);
                }
            }
            return Double.valueOf(resultStack.pop());
        }
    
        /**
         * 数据准备阶段将表达式转换成为后缀式栈
         * @param expression
         */
        private void prepare(String expression) {
            opStack.push(',');//运算符放入栈底元素逗号,此符号优先级最低
            char[] arr  = expression.toCharArray();
            int currentIndex  = 0;//当前字符的位置
            int count = 0;//上次算术运算符到本次算术运算符的字符的长度便于或者之间的数值
            char currentOp  ,peekOp;//当前操作符和栈顶操作符
            for(int i=0;i<arr.length;i++) {
                currentOp = arr[i];
                if(isOperator(currentOp)) {//如果当前字符是运算符
                    if(count > 0) {
                        postfixStack.push(new String(arr,currentIndex,count));//取两个运算符之间的数字
                    }
                    peekOp = opStack.peek();
                    if(currentOp == ')') {//遇到反括号则将运算符栈中的元素移除到后缀式栈中直到遇到左括号
                        while(opStack.peek() != '(') {
                            postfixStack.push(String.valueOf(opStack.pop()));
                        }
                        opStack.pop();
                    } else {
                        while(currentOp != '(' && peekOp != ',' && compare(currentOp,peekOp) ) {
                            postfixStack.push(String.valueOf(opStack.pop()));
                            peekOp = opStack.peek();
                        }
                        opStack.push(currentOp);
                    }
                    count = 0;
                    currentIndex = i+1;
                } else {
                    count++;
                }
            }
            if(count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {//最后一个字符不是括号或者其他运算符的则加入后缀式栈中
                postfixStack.push(new String(arr,currentIndex,count));
            } 
    
            while(opStack.peek() != ',') {
                postfixStack.push(String.valueOf( opStack.pop()));//将操作符栈中的剩余的元素添加到后缀式栈中
            }
        }
    
        /**
         * 判断是否为算术符号
         * @param c
         * @return
         */
        private boolean isOperator(char c) {
            return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' ||c == ')';
        }
    
        /**
         * 利用ASCII码-40做下标去算术符号优先级
         * @param cur
         * @param peek
         * @return
         */
        public  boolean compare(char cur,char peek) {// 如果是peek优先级高于cur,返回true,默认都是peek优先级要低
            boolean result  = false;
            if(operatPriority[(peek)-40] >= operatPriority[(cur) - 40]) {
               result = true;
            }
            return result;
        }
    
        /**
         * 按照给定的算术运算符做计算
         * @param firstValue
         * @param secondValue
         * @param currentOp
         * @return
         */
        private String calculate(String firstValue,String secondValue,char currentOp) {
            String result  = "";
            switch(currentOp) {
                case '+':
                    result = String.valueOf(ArithHelper.add(firstValue, secondValue));
                    break;
                case '-':
                    result = String.valueOf(ArithHelper.sub(firstValue, secondValue));
                    break;
                case '*':
                    result = String.valueOf(ArithHelper.mul(firstValue, secondValue));
                    break;
                case '/':
                    result = String.valueOf(ArithHelper.div(firstValue, secondValue));
                    break;
            }
            return result;
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 笔记本上移动热点开关状态查询
  • ¥85 类鸟群Boids——仿真鸟群避障的相关问题
  • ¥15 CFEDEM自带算例错误,如何解决?
  • ¥15 有没有会使用flac3d软件的家人
  • ¥20 360摄像头无法解绑使用,请教解绑当前账号绑定问题,
  • ¥15 docker实践项目
  • ¥15 利用pthon计算薄膜结构的光导纳
  • ¥15 海康hlss视频流怎么播放
  • ¥15 Paddleocr:out of memory error on GPU
  • ¥30 51单片机C语言数码管驱动单片机为AT89C52