当前位置:首页 > 后端开发 > 正文

Java计算器如何添加算法?

在Java计算器中添加算法需实现运算逻辑与界面交互的整合,核心步骤包括:设计算法类处理四则运算、括号优先级及科学计算函数;使用栈结构解析表达式(如逆波兰算法);通过事件监听捕获用户输入;最后将计算结果实时反馈到显示组件,需特别注意异常处理(如除零错误)和浮点精度控制。

核心算法设计

  1. 基本运算逻辑

    • 四则运算算法:使用栈(Stack)处理运算符优先级(如乘除优先于加减)

      public double calculate(String expression) {
          Stack<Double> numbers = new Stack<>();
          Stack<Character> operators = new Stack<>();
          for (int i = 0; i < expression.length(); i++) {
              char c = expression.charAt(i);
              if (Character.isDigit(c)) {
                  // 处理多位数
                  StringBuilder num = new StringBuilder();
                  while (i < expression.length() && (Character.isDigit(expression.charAt(i)) || expression.charAt(i) == '.')) {
                      num.append(expression.charAt(i++));
                  }
                  i--;
                  numbers.push(Double.parseDouble(num.toString()));
              } else if (c == '(') {
                  operators.push(c);
              } else if (c == ')') {
                  while (operators.peek() != '(') {
                      processOperation(numbers, operators.pop());
                  }
                  operators.pop(); // 移除 '('
              } else if (isOperator(c)) {
                  // 比较优先级:当前运算符优先级 <= 栈顶则先计算
                  while (!operators.isEmpty() && getPriority(c) <= getPriority(operators.peek())) {
                      processOperation(numbers, operators.pop());
                  }
                  operators.push(c);
              }
          }
          while (!operators.isEmpty()) {
              processOperation(numbers, operators.pop());
          }
          return numbers.pop();
      }
      private void processOperation(Stack<Double> numbers, char op) {
          double b = numbers.pop();
          double a = numbers.pop();
          switch (op) {
              case '+': numbers.push(a + b); break;
              case '-': numbers.push(a - b); break;
              case '*': numbers.push(a * b); break;
              case '/': 
                  if (b == 0) throw new ArithmeticException("除零错误");
                  numbers.push(a / b); break;
          }
      }
  2. 高级函数扩展

    • 科学计算算法:集成Math类实现幂、开方、三角函数
      public double handleScientificFunc(String func, double num) {
          return switch (func) {
              case "sqrt" -> Math.sqrt(num);
              case "pow" -> Math.pow(num, 2); // 平方
              case "sin" -> Math.sin(Math.toRadians(num));
              default -> throw new IllegalArgumentException("无效函数");
          };
      }

关键实现细节

  1. 表达式解析

    Java计算器如何添加算法?  第1张

    • 使用正则表达式拆分输入:"10+3.2*sin(45)" → ["10", "+", "3.2", "*", "sin", "(", "45", ")"]
    • 处理负数:在表达式起始或运算符后出现时标记为负号而非减号。
  2. 异常处理

    • 自定义异常类提升健壮性:
      try {
          result = calculate(expression);
      } catch (ArithmeticException e) {
          System.out.println("错误: " + e.getMessage());
      } catch (EmptyStackException e) {
          System.out.println("表达式不合法");
      }
  3. 内存功能算法

    • 实现MC(清除)、MR(读取)、M+(累加):

      private double memory = 0;
      public void memoryClear() { memory = 0; }
      public double memoryRecall() { return memory; }
      public void memoryAdd(double value) { memory += value; }

性能与安全优化

  1. 算法效率

    • 时间复杂度:O(n)(单次遍历表达式)
    • 使用StringBuilder替代字符串拼接减少内存开销。
  2. 输入验证

    • 防止SQL注入/XSS攻击(Web版):
      if (!expression.matches("[0-9+\-*/().sqrt^sinco]+")) {
          throw new IllegalArgumentException("非规字符");
      }
  3. 精度处理

    • BigDecimal替代double避免浮点误差:
      BigDecimal a = new BigDecimal("0.1");
      BigDecimal b = new BigDecimal("0.2");
      System.out.println(a.add(b)); // 0.3

测试与调试

  1. 单元测试用例
    @Test
    public void testCalculate() {
        assertEquals(8.0, calculate("3 + 5"));
        assertEquals(6.0, calculate("2 * (1 + 2)"));
        assertEquals(1.0, calculate("sin(90)"), 0.001); // 允许误差
    }
  2. 边界测试
    • 超大数:1e308 * 2 → 返回Infinity
    • 连续运算符:5+-3 → 解析为5 + (-3)

进阶扩展方向

  1. 支持变量与函数
    • 使用HashMap<String, Double>存储变量(如π=3.14
  2. 表达式可视化

    集成JavaFX绘制计算过程树形图

  3. 历史记录
    • LinkedList保存最近10次计算记录

引用说明

  • 运算符优先级算法参考《算法导论》(Thomas H. Cormen)
  • Math类函数规范源自Oracle官方文档
  • 安全实践符合OWASP输入验证标准(2025版)

通过分层设计算法模块、严格验证输入、覆盖异常场景,可构建出符合工业级标准的计算器应用,建议结合Swing或JavaFX实现GUI,完整代码参考GitHub开源项目JavaCalculator。

0