qq_40247765 2022-03-20 08:21 采纳率: 100%
浏览 148
已结题

输入一个表达式(用字符串表示),求这个表达式的值

输入一个表达式(用字符串表示) 求这个表达式的值
保证字符串中的有效字符包括[‘0’-‘9’] ‘(’, ‘)’ 且表达式一定合法。

数据范围:表达式计算结果和过程中满足 |val| \le 1000 \ ∣val∣≤1000 字符串长度满足 1 \le n \le 1000 \ 1≤n≤1000

输出描述
得到计算结果

问一下在使用双栈法的情况下 程序运行的过程 比如输入3+2(-4/(64*8-6+3)+7) 计算第一个括号内的内容时 是把哪个数 哪个符号压入栈 计算第二个括号 以此类推

  • 写回答

2条回答 默认 最新

  • 关注

    img

    import java.math.BigDecimal;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Stack;
    
    /**
     * 对表达式求值,支持加减乘除括号小数点,不支持负数
     */
     public class Operation {
        //优先级Map
        private static final Map<String,Integer> OP_PRIORITY_MAP=new HashMap<String, Integer>(){
            {
                put("(",0);
                put("+",3);
                put("-",3);
                put("*",4);
                put("/",4);
                put(")",10);
            }
        };
    
        public double operationExpression(String expression){
            Stack<String> opStack = new Stack<String>();         //运算符栈
            Stack<BigDecimal> numStack = new Stack<BigDecimal>();       //操作数栈
            StringBuilder numBuilder = new StringBuilder();     //当前数值的追加器
    
            for (int i = 0;i < expression.length();i++){
                char c = expression.charAt(i);
                if (c >= '0' && c <= '9' || c == '.'){          //如果是数值则加入追加器
                    numBuilder.append(c);
                }else{                                          //如果是运算符
                    if (numBuilder.length() > 0){               //如果numBuilder有值说明里面已经有一个数值
                        numStack.push(new BigDecimal(numBuilder.toString()));     //把数值入运算符栈
                        numBuilder.delete(0,numBuilder.length());  //清空数值
                    }
                    //读取到的字符是运算符
                    String op = String.valueOf(c);
                    if (opStack.empty()){    //如果操作数栈没有运算符
                        opStack.push(op);
                    }else{
                        //如果是"("则直接入运算栈
                        if ("(".equals(op)){
                            opStack.push(op);
                        }else if (")".equals(op)){
                            //如果是")"则进行括号匹配运算括号内的表达式
                            while (!"(".equals(opStack.peek())){
                                stackOperation(opStack,numStack);
                            }
                            opStack.pop();
                        }else{
                            //如果是运算符,需要对比当前运算符op和栈顶的运算符优先级。
                            do {
                                //比较当前运算符和栈顶运算符的优先级,如果nowOp和opStack栈顶元素相同或者低级,
                                // 则进行运算,直到nowOp高于opStack栈顶
                                if (jubgmentPriority(op,opStack.peek())){
                                    stackOperation(opStack,numStack);
                                    if (opStack.empty()){
                                        opStack.push(op);
                                        break;
                                    }
                                }else {
                                    opStack.push(op);
                                    break;
                                }
                            }while (!opStack.empty());
                        }
                    }
                }
            }
    
            //表达式结束,追加器里面有值
            if (numBuilder.length()>0){
                numStack.push(new BigDecimal(numBuilder.toString()));
            }
    
            while (!opStack.empty()){
                stackOperation(opStack,numStack);
            }
            return numStack.pop().doubleValue();
        }
    
        /**
         * 进行一次二元运算
         * @param opStack
         * @param numStack
         */
        public void stackOperation(Stack<String> opStack,Stack<BigDecimal> numStack){
            String opT = opStack.pop();              //栈顶运算符
            BigDecimal num2 = numStack.pop();       //第二个操作数
            BigDecimal num1 = numStack.pop();       //第一个操作数
            BigDecimal operationNum = oneOperation(opT,num1,num2);   //num1 op num2
    
            numStack.push(operationNum);            //把计算完的结果放入操作数栈
        }
    
    
    //
    
        /**
         * 单次计算,计算为num1 op num2
         * @param op    运算符
         * @param num1  第一个操作数
         * @param num2  第二个操作数
         * @return  num1 op num2
         */
        public BigDecimal oneOperation(String op,BigDecimal num1,BigDecimal num2){
            BigDecimal result = new BigDecimal(0);
            switch (op){
                case "+":
                    result = num1.add(num2);
                    break;
                case "-":
                    result = num1.subtract(num2);
                    break;
                case "*":
                    result = num1.multiply(num2);
                    break;
                case "/":
                    result = num1.divide(num2);
                    break;
                default:
                    break;
            }
            return result;
        }
    
    
        /**
         * 比较运算符优先级
         * @param op1
         * @param op2
         * @return op1比op2相同或低级则返回true,op1比op2高级则返回false
         */
        private boolean jubgmentPriority(String op1, String op2){
            return (OP_PRIORITY_MAP.get(op1) - OP_PRIORITY_MAP.get(op2)) <= 0;
        }
    
        public static void main(String[] args) {
            Operation operation = new Operation();
            System.out.println(operation.operationExpression("(2+2)*3+3+3/3+2.2"));
        }}
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)
编辑
预览

报告相同问题?

问题事件

  • 系统已结题 3月28日
  • 已采纳回答 3月21日
  • 修改了问题 3月20日
  • 创建了问题 3月20日

悬赏问题

  • ¥15 KeiI中头文件找不到怎么解决
  • ¥15 QT6将音频采样数据转PCM
  • ¥15 本地安装org.Hs.eg.dby一直这样的图片报错如何解决?
  • ¥15 下面三个文件分别是OFDM波形的数据,我的思路公式和我写的成像算法代码,有没有人能帮我改一改,如何解决?
  • ¥15 Ubuntu打开gazebo模型调不出来,如何解决?
  • ¥100 有chang请一位会arm和dsp的朋友解读一个工程
  • ¥50 求代做一个阿里云百炼的小实验
  • ¥15 查询优化:A表100000行,B表2000 行,内存页大小只有20页,运行时3页,设计两个表等值连接的最简单的算法
  • ¥15 led数码显示控制(标签-流程图)
  • ¥20 为什么在复位后出现错误帧