Java计算器
介绍
计算器是我们日常生活中非常常见的工具,它可以帮助我们进行简单的数学运算。而在计算机科学领域中,我们也可以开发出一款计算器软件,用于进行更复杂的计算和数学运算。本文将介绍如何使用Java编写一个简单的计算器程序,并提供相应的代码示例。
计算器功能
一款基本的计算器软件通常具备以下功能:
- 四则运算:加法、减法、乘法和除法。
- 括号运算:支持使用括号改变运算顺序。
- 优先级:支持正确的数学优先级。
- 小数运算:支持小数运算。
- 清除操作:支持清除当前输入或全部输入。
设计思路
为了实现上述功能,我们可以使用逆波兰表达式(Reverse Polish Notation,RPN)来计算表达式的值。逆波兰表达式是一种无括号的数学表达式表示法,它将操作数放在运算符之前,可以避免括号运算和优先级的问题。
基于逆波兰表达式,我们可以设计一个计算器类来进行计算。计算器类需要具备以下功能:
- 输入表达式:接受用户输入的数学表达式。
- 转换表达式:将中缀表达式转换为逆波兰表达式。
- 计算结果:根据逆波兰表达式计算出结果。
代码示例
下面是一个简单的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;