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

Java支持批量累积运算的Calculator计算器实现需求与接口规范

Java批量累积运算计算器实现

功能说明

我们需要实现一款支持批量运算的Java计算器,工作逻辑如下:

  • 首个运算接收操作符和两个操作数
  • 后续运算自动将前一次运算结果作为当前运算的第一个操作数,仅需传入额外1个新操作数即可,非首个运算传入的第二个操作数会被自动忽略
  • 支持+、-、*、/四种运算
  • 批量运算执行完成后(即使执行过程中抛出异常)会自动清空所有内部状态

完整实现代码

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

public class Calculator {
    // 合法操作符集合
    private static final Set<String> VALID_OPERATIONS = Set.of("+", "-", "*", "/");
    // 运算节点内部类,存储单步运算信息
    private static class OpNode {
        String op;
        float num1;
        float num2;
        boolean isFirstOp;

        public OpNode(String op, float num1, float num2, boolean isFirstOp) {
            this.op = op;
            this.num1 = num1;
            this.num2 = num2;
            this.isFirstOp = isFirstOp;
        }
    }

    private final List<OpNode> opNodes = new ArrayList<>();

    /**
     * 计算器公共构造方法
     */
    public Calculator () {}

    /**
     * 清除计算器的内部状态
     */
    public void cleanOperations () {
        opNodes.clear();
    }

    /**
     * 向计算器内部状态添加新运算。
     * 计算器采用累积运算逻辑:仅首个运算需要两个操作数,后续运算均使用累积值加1个额外新操作数计算,非首个运算传入的第二个操作数将被忽略。
     *
     * @param operation 待添加的运算操作符,字符串类型,支持"+"、"-"、"*"、"/"
     * @param values 新运算的操作数,支持1个或2个,使用Java varargs可变参数特性
     * @throws IllegalArgumentException 传入操作符不合法、操作数数量不足时抛出
     */
    public void addOperation(String operation , float ... values) {
        // 操作符合法性校验
        if (!VALID_OPERATIONS.contains(operation)) {
            throw new IllegalArgumentException("不支持的操作符:" + operation);
        }
        boolean isFirst = opNodes.isEmpty();
        // 操作数数量校验
        if (isFirst && values.length < 2) {
            throw new IllegalArgumentException("首次运算需要至少2个操作数");
        }
        if (!isFirst && values.length < 1) {
            throw new IllegalArgumentException("运算需要至少1个操作数");
        }
        // 存储运算节点
        if (isFirst) {
            opNodes.add(new OpNode(operation, values[0], values[1], true));
        } else {
            opNodes.add(new OpNode(operation, 0, values[0], false));
        }
    }

    /**
     * 执行计算器内部存储的所有批量运算。
     * 执行完成后(即便执行过程中抛出异常),内部存储的操作数和运算都会被清空重置,计算器采用运算批量处理模式。
     * @return 所有运算执行后的最终结果
     * @throws ArithmeticException 运算出现非法值(如除零)时抛出
     */
    public float executeOperations () {
        float result = 0f;
        try {
            if (opNodes.isEmpty()) {
                return result;
            }
            // 执行首个运算
            OpNode firstNode = opNodes.get(0);
            result = calcSingle(firstNode.op, firstNode.num1, firstNode.num2);
            // 执行后续累积运算
            for (int i = 1; i < opNodes.size(); i++) {
                OpNode current = opNodes.get(i);
                result = calcSingle(current.op, result, current.num2);
            }
            return result;
        } finally {
            // 无论运算是否异常都清空状态
            cleanOperations();
        }
    }

    /**
     * 单步运算逻辑封装
     */
    private float calcSingle(String op, float a, float b) {
        switch (op) {
            case "+": return a + b;
            case "-": return a - b;
            case "*": return a * b;
            case "/":
                if (b == 0f) {
                    throw new ArithmeticException("除零运算错误");
                }
                return a / b;
            default:
                throw new IllegalArgumentException("不支持的操作符:" + op);
        }
    }

    /**
     * 输出计算器当前内部状态字符串,格式要求:
     * "[{+/ -/"/"/*}] value1_value2 [{+/ -/"/"/*}] value1 [{+/ -/"/"/*}] value1 {...}"
     * @return 计算器内部状态字符串
     */
    @Override
    public String toString () {
        StringBuilder sb = new StringBuilder("[STATE:");
        for (OpNode node : opNodes) {
            sb.append("[").append(node.op).append("]");
            if (node.isFirstOp) {
                sb.append(node.num1).append("_").append(node.num2);
            } else {
                sb.append(node.num2);
            }
        }
        sb.append("]");
        return sb.toString();
    }
}

测试验证

上述实现可直接通过给定测试用例:

float EPSILON = 0.01f;
Calculator calculator = new Calculator();
// 添加运算
calculator.addOperation("+", 4.5f, 6.8f);
calculator.addOperation("-", 3.1f);
calculator.addOperation("/", 6f);
// 校验状态字符串
assertEquals("[STATE:[+]4.5_6.8[-]3.1[/]6.0]", calculator.toString());
// 执行运算
float result = calculator.executeOperations();
// 校验执行后状态清空
assertEquals("[STATE:]", calculator.toString());
// 校验运算结果误差符合要求
assertEquals(1.366f, result, EPSILON);

运算过程:(4.5 + 6.8 - 3.1) / 6 = 8.2 / 6 ≈ 1.3667,符合0.01误差范围要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 10:39:03