Java实现空格分隔四则运算表达式求值(支持+−×÷,精确到小数点后2位)
以下是使用 **Java** 编写的完整解决方案,用于计算只含 `+`、`-`、`*`、`/` 和非负整数的简单算术表达式(空格分隔),支持多行输入,输出结果保留 **小数点后2位**(即使为整数也输出如 `3.00`)。 ✅ 特点说明: - 严格按题意:**运算符与数字间用空格分隔**(如 `"1 + 2"`),无括号、无负数、无非法输入; - 使用 **双栈(操作数栈 + 运算符栈)** 或更优的 **“先乘除后加减”单遍扫描法**(推荐); - 本解采用 **一次线性扫描 + 延迟计算乘除** 的高效方式(O(n) 时间,O(1) 空间),避免栈开销,简洁可靠; - 使用 `double` 存储中间结果,确保除法精度; - 输出统一格式化为 `%.2f`(自动四舍五入,补零)。 --- ### ✅ Java 完整可运行代码(含主方法,支持多行输入): ```java import java.util.Scanner; public class SimpleCalculator { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNextLine()) { String line = sc.nextLine().trim(); if (line.isEmpty()) continue; double result = evaluate(line); System.out.printf("%.2f\n", result); } sc.close(); } public static double evaluate(String s) { // 分割空格 → 得到 tokens: ["1", "+", "2", "*", "3"] String[] tokens = s.split("\\s+"); if (tokens.length == 0) return 0.0; // 初始化:第一个数为 operand,prev 表示上一个待参与运算的“项”(用于处理 * /) double result = 0.0; double prev = Double.parseDouble(tokens[0]); // 当前累积的“项”(如 a + b*c-d → b*c 是一个项) char lastOp = '+'; // 虚拟前置运算符,让第一个数被加到 result // 从第1个token开始(即第一个运算符),步长为2:tokens[1], tokens[3], ... for (int i = 1; i < tokens.length; i += 2) { if (i + 1 >= tokens.length) break; // 防御:确保有下一个数字 char op = tokens[i].charAt(0); double num = Double.parseDouble(tokens[i + 1]); switch (op) { case '+': result += prev; prev = num; break; case '-': result += prev; prev = -num; break; case '*': prev = prev * num; break; case '/': prev = prev / num; break; default: // 题目保证无非法字符,可忽略 } } result += prev; // 加上最后一个未累加的项 return result; } } ``` --- ### 🔍 算法原理简析(为什么这样写?) 该算法基于 **“加减是顶层运算,乘除是原子项”** 思想: - 将表达式视为若干“带符号项”的和: `1 + 2 * 3 - 4 / 2` → `(+1) + (+2*3) + (-4/2)` → `1 + 6 + (-2) = 5` - 维护: - `result`: 已确定加入总和的部分(如 `+1` 后,`result=0`, `prev=1`;遇到 `+` 时把 `prev` 加入 `result`,重置 `prev`); - `prev`: 当前正在构建的“项”,受最近 `+`/`-` 影响,并持续被 `*`/`/` 修改; - 每遇到 `+` 或 `-`,就把当前 `prev` 累加进 `result`,然后以新符号初始化下一个 `prev`; - 每遇到 `*` 或 `/`,直接修改 `prev`(不碰 `result`),体现其高优先级。 ✅ 此法无需栈、不递归、不建树,简洁高效,且天然支持题目限定格式。 --- ### 🧪 测试样例验证: | 输入 | 输出 | 说明 | |-------------------|--------|--------------------------| | `1 + 2` | `3.00` | `1+2 = 3` | | `10 - 3 * 2` | `4.00` | `10 - (3*2) = 4` | | `8 / 2 + 1` | `5.00` | `(8/2)+1 = 4+1 = 5` | | `100 * 0 / 5` | `0.00` | `100*0=0 → 0/5=0` | | `7` | `7.00` | 单数字(tokens.length==1)| > ✅ 所有情况均正确 —— 因 `evaluate()` 中 `tokens.length==1` 时,`for` 循环不执行,直接 `return prev = Double.parseDouble(tokens[0])` --- ######[AI写代码神器 | 1275点数解答 | 2026-04-15 15:45:37]
- 递归下降语法分析程序实例:从文法到 C 代码的完整实现(字节豆包 | 1371点数解答 | 2024-12-12 22:46:04)270
- Java 实现复制粘贴功能:打造简易文本复制粘贴程序(GPT | 1497点数解答 | 2024-08-25 09:40:33)416
- Python 实现实数四则运算:输入表达式输出结果,处理除零与格式错误(字节豆包 | 286点数解答 | 2024-11-17 11:21:58)142
- C 语言实现:输入实数四则运算式输出保留两位小数结果(含特殊情况处理) (字节豆包 | 320点数解答 | 2024-11-17 11:22:27)154
- SQL 实现:精准查询 20 岁选课学生学号、姓名、平均与总成绩(去重取最高) (字节豆包 | 116点数解答 | 2024-10-21 00:46:57)215
- 解决数据库“dm.jdbc.driver.dmexception: 数据溢出”问题的全步骤指南(阿里通义 | 598点数解答 | 2024-10-15 15:48:38)320
- 达梦数据库数据溢出问题排查及多维度解决方法(阿里通义 | 403点数解答 | 2024-10-15 15:48:41)1191
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)359
- Java顺序表源码深度解析:从内存布局到扩容机制与Windows实战指南(阿里通义 | 2528点数解答 | 2026-04-01 10:06:46)18
- C++实现九九乘法表输出及代码详细解释(字节豆包 | 412点数解答 | 2026-02-06 22:10:32)75
- 手把手教你:从安居客大连二手房页面精准爬取关键信息!(GPT | 854点数解答 | 2024-11-02 08:56:33)336
- 手把手教你:从安居客大连二手房页面精准爬取关键信息的解析函数(GPT | 792点数解答 | 2024-11-02 08:58:39)297