Java计算器如何添加算法?

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

核心算法设计

  1. 基本运算逻辑

    Java计算器如何添加算法?

    • 四则运算算法:使用栈(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. 表达式解析

    • 使用正则表达式拆分输入:"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. 内存功能算法

    Java计算器如何添加算法?

    • 实现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绘制计算过程树形图

    Java计算器如何添加算法?

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

引用说明

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

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

原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/31352.html

(0)
酷盾叔的头像酷盾叔
上一篇 2025年6月19日 21:01
下一篇 2025年6月9日 03:50

相关推荐

  • Java如何设置组件高度和宽度?

    在Java中设置组件高度宽度可通过setSize(int width, int height)方法直接指定像素值,或使用setPreferredSize(new Dimension(width, height))配合布局管理器,Swing组件还支持setMinimumSize()/setMaximumSize()控制尺寸范围,JavaFX则用setPrefWidth()/setPrefHeight()方法实现弹性布局。

    2025年6月15日
    000
  • Java点击按钮如何跳转页面

    在Java中实现按钮跳转窗口,可通过事件监听器触发,常见步骤:创建按钮并添加ActionListener,在actionPerformed方法中实例化目标窗口(如JFrame),设置可见性,同时可关闭当前窗口,Swing或JavaFX均可实现此功能。

    2025年6月15日
    000
  • Java如何高效存储数据?

    在Java中可通过变量存储基本数据,集合框架(如List/Map)管理对象组,数组存放同类型元素,文件/数据库持久化数据,或利用对象封装属性实现结构化存储。

    2025年6月2日
    300
  • Java时间轴如何实现

    使用Java创建时间轴可借助Swing/JavaFX组件或JFreeChart等库,核心步骤:定义时间-事件数据结构,通过自定义面板绘制水平/垂直线性轴,动态标记刻度及事件节点,并添加交互事件(如点击查看详情),JavaFX的Canvas或Timeline类能简化动画效果实现。

    2025年6月10日
    000
  • 如何用Java替换图片?

    使用Java代码实现图片替换,核心是覆盖源文件或修改图片内容,通过文件操作直接替换磁盘图片文件,或利用ImageIO、Graphics2D等处理图片内容后保存覆盖。

    2025年6月3日
    400

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN