Java计算器混合运算实现问题:支持双精度浮点数、负数及多位数计算
问题核心缺陷
你当前的实现存在两个核心问题:
- 硬编码截取运算符前后1位字符的逻辑,天然不支持多位数、浮点数、前缀负号的解析
- 没有统一的运算符优先级处理逻辑,扩展成本极高
推荐实现方案
采用**中缀转后缀表达式(逆波兰表达式)**的方案实现,可完美兼容双精度浮点数、负数、多位数、混合运算优先级的要求,实现步骤如下:
- 词法分析:将输入字符串拆分为数字(含负数、浮点数)和运算符两类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
相关产品推荐
相关产品推荐

