Java计算器

介绍

计算器是我们日常生活中非常常见的工具,它可以帮助我们进行简单的数学运算。而在计算机科学领域中,我们也可以开发出一款计算器软件,用于进行更复杂的计算和数学运算。本文将介绍如何使用Java编写一个简单的计算器程序,并提供相应的代码示例。

计算器功能

一款基本的计算器软件通常具备以下功能:

  1. 四则运算:加法、减法、乘法和除法。
  2. 括号运算:支持使用括号改变运算顺序。
  3. 优先级:支持正确的数学优先级。
  4. 小数运算:支持小数运算。
  5. 清除操作:支持清除当前输入或全部输入。

设计思路

为了实现上述功能,我们可以使用逆波兰表达式(Reverse Polish Notation,RPN)来计算表达式的值。逆波兰表达式是一种无括号的数学表达式表示法,它将操作数放在运算符之前,可以避免括号运算和优先级的问题。

基于逆波兰表达式,我们可以设计一个计算器类来进行计算。计算器类需要具备以下功能:

  1. 输入表达式:接受用户输入的数学表达式。
  2. 转换表达式:将中缀表达式转换为逆波兰表达式。
  3. 计算结果:根据逆波兰表达式计算出结果。

代码示例

下面是一个简单的Java计算器示例,展示了如何实现上述功能:

import java.util.Stack;

public class Calculator {
    // 运算符优先级
    private static final int ADD = 1;
    private static final int SUBTRACT = 1;
    private static final int MULTIPLY = 2;
    private static final int DIVIDE = 2;

    // 判断字符是否是运算符
    private static boolean isOperator(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    // 获取运算符的优先级
    private static int getPriority(char operator) {
        if (operator == '+' || operator == '-') {
            return ADD;
        } else if (operator == '*' || operator == '/') {
            return MULTIPLY;
        } else {
            throw new IllegalArgumentException("Invalid operator: " + operator);
        }
    }

    // 将中缀表达式转换为逆波兰表达式
    private static String convertToRPN(String infix) {
        StringBuilder rpn = new StringBuilder();
        Stack<Character> stack = new Stack<>();

        for (char c : infix.toCharArray()) {
            if (Character.isWhitespace(c)) {
                continue;
            }

            if (Character.isDigit(c) || c == '.') {
                rpn.append(c);
            } else if (isOperator(c)) {
                while (!stack.isEmpty() && isOperator(stack.peek()) &&
                        getPriority(stack.peek()) >= getPriority(c)) {
                    rpn.append(stack.pop());
                }
                stack.push(c);
            } else if (c == '(') {
                stack.push(c);
            } else if (c == ')') {
                while (!stack.isEmpty() && stack.peek() != '(') {
                    rpn.append(stack.pop());
                }
                stack.pop(); // 弹出左括号
            } else {
                throw new IllegalArgumentException("Invalid character: " + c);
            }
        }

        while (!stack.isEmpty()) {
            if (stack.peek() == '(' || stack.peek() == ')') {
                throw new IllegalArgumentException("Invalid infix expression");
            }
            rpn.append(stack.pop());
        }

        return rpn.toString();
    }

    // 根据逆波兰表达式计算结果
    private static double calculateRPN(String rpn) {
        Stack<Double> stack = new Stack<>();

        for (char c : rpn.toCharArray()) {
            if (Character.isDigit(c)) {
                stack.push(Double.parseDouble(String.valueOf(c)));
            } else if (isOperator(c)) {
                double operand2 = stack.pop();
                double operand1 = stack.pop();

                switch (c) {
                    case '+':
                        stack.push(operand1 + operand2);
                        break;
                    case '-':
                        stack.push(operand1 - operand2);
                        break;
                    case '*':
                        stack.push(operand1 * operand2);
                        break;
                    case '/':
                        stack.push(operand1 / operand2);
                        break;