You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java计算器混合运算实现问题:支持双精度浮点数、负数及多位数计算

问题核心缺陷

你当前的实现存在两个核心问题:

  1. 硬编码截取运算符前后1位字符的逻辑,天然不支持多位数、浮点数、前缀负号的解析
  2. 没有统一的运算符优先级处理逻辑,扩展成本极高

推荐实现方案

采用**中缀转后缀表达式(逆波兰表达式)**的方案实现,可完美兼容双精度浮点数、负数、多位数、混合运算优先级的要求,实现步骤如下:

  • 词法分析:将输入字符串拆分为数字(含负数、浮点数)和运算符两类token
  • 中缀转后缀:按照乘除 > 加减的优先级,结合栈结构完成表达式转换
  • 后缀表达式计算:用栈结构完成最终运算

完整可运行代码

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

public class MixedCalculator {
    // 运算符优先级定义
    private static int getPriority(char op) {
        if (op == '+' || op == '-') return 1;
        if (op == '*' || op == '/') return 2;
        return 0;
    }

    // 词法分析:拆分表达式为token列表
    private static List<String> tokenize(String expr) {
        List<String> tokens = new ArrayList<>();
        StringBuilder numBuf = new StringBuilder();
        for (int i = 0; i < expr.length(); i++) {
            char c = expr.charAt(i);
            // 数字、小数点、前缀负号(负号出现在开头或前一个字符是运算符)
            if (Character.isDigit(c) || c == '.' || (c == '-' && (i == 0 || getPriority(expr.charAt(i-1)) > 0))) {
                numBuf.append(c);
            } else {
                // 运算符,先把之前缓存的数字存入token
                if (numBuf.length() > 0) {
                    tokens.add(numBuf.toString());
                    numBuf.setLength(0);
                }
                tokens.add(String.valueOf(c));
            }
        }
        // 最后一个数字存入token
        if (numBuf.length() > 0) {
            tokens.add(numBuf.toString());
        }
        return tokens;
    }

    // 中缀表达式转后缀表达式
    private static List<String> infixToPostfix(List<String> infixTokens) {
        List<String> postfix = new ArrayList<>();
        Stack<Character> opStack = new Stack<>();
        for (String token : infixTokens) {
            // 数字直接加入后缀表达式
            if (token.matches("-?\\d+(\\.\\d+)?")) {
                postfix.add(token);
            } else {
                char op = token.charAt(0);
                // 栈顶运算符优先级 >= 当前运算符,弹出栈顶到后缀表达式
                while (!opStack.isEmpty() && getPriority(opStack.peek()) >= getPriority(op)) {
                    postfix.add(String.valueOf(opStack.pop()));
                }
                opStack.push(op);
            }
        }
        // 剩余运算符全部弹出
        while (!opStack.isEmpty()) {
            postfix.add(String.valueOf(opStack.pop()));
        }
        return postfix;
    }

    // 计算后缀表达式
    private static double calculatePostfix(List<String> postfix) {
        Stack<Double> numStack = new Stack<>();
        for (String token : postfix) {
            if (token.matches("-?\\d+(\\.\\d+)?")) {
                numStack.push(Double.parseDouble(token));
            } else {
                double b = numStack.pop();
                double a = numStack.pop();
                switch (token.charAt(0)) {
                    case '+': numStack.push(a + b); break;
                    case '-': numStack.push(a - b); break;
                    case '*': numStack.push(a * b); break;
                    case '/': numStack.push(a / b); break;
                }
            }
        }
        return numStack.pop();
    }

    // 对外暴露的计算方法
    public static double calc(String expr) {
        List<String> infix = tokenize(expr);
        List<String> postfix = infixToPostfix(infix);
        return calculatePostfix(postfix);
    }

    public static void main(String[] args) {
        // 测试你要求的样例
        String testExpr = "-73.5*4+744/2+76-6";
        System.out.println(calc(testExpr)); // 输出结果为148.0
    }
}

代码适配说明

  • 支持任意多位数、双精度浮点数运算
  • 支持前缀负号的数字解析
  • 自动按照先乘除后加减的优先级处理运算
  • 可直接替换你原有代码的运算逻辑,只需要调用calc(用户输入的运算表达式)即可拿到结果

内容的提问来源于stack exchange,提问作者Jcorderop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:36:03