1. 中缀计算器
public class InfixCalculator {
/**
* @author - hoy
* 计算器:计算所给出数学表达式字符串的结果,返回结果值(只计算个位数的数字输入,无括号)
* @param expression - 表达式字符串
* @return - 返回计算结果
*/
public static int infixCalculator(String expression) {
// 1. 若字符串为空或null,抛出异常
if (expression == null || expression.isEmpty()) {
throw new RuntimeException("null or empty");
}
// 2. 设置两个栈,一个储存数字,一个储存运算符号
ArrayStack2 digitStack = new ArrayStack2(expression.length());
ArrayStack2 operatorStack = new ArrayStack2(expression.length());
// 3. 设置必要的变量
int number1 = 0;
int number2 = 0;
int operator = 0;
int result = 0;
String wholeNumber = "";
// 4. 遍历expression,逐个处理字符
for (int i = 0; i < expression.length(); i++) {
// 4.1 获取当前字符
char currentChar = expression.charAt(i);
// 4.2 若为 运算符
if (ArrayStack2.isValidOperator(currentChar)) {
// 4.2.1 当运算符栈非空 且 栈顶为'*'时,开始循环计算栈内现有的乘法(因为只要遇到'/'就计算了,所以只会有'*'
while (!operatorStack.isEmpty() && operatorStack.peekTop() == '*') {
// (1) 数字栈取两个数字,取出栈顶字符
number1 = digitStack.pop();
number2 = digitStack.pop();
operator = operatorStack.pop();
// (2) 若运算符栈非空
if (!operatorStack.isEmpty()) {
// 若两个字符同级,若前一个字符为"-",则改当前字符为同级的另一字符
operator = ArrayStack2.changeOperator(operator, operatorStack.peekTop());
}
// (3) 计算结果
result = ArrayStack2.calculator(number1, number2, operator);
// (4) 结果入数字栈
digitStack.push(result);
}
// 4.2.2 当前字符入运算符栈
operatorStack.push(currentChar);
}
// 4.3 若为 数字:直接入数字栈(但要做"数字拼接"处理)
else if (digitStack.isValidNumber(currentChar)) {
// 4.3.1 拼接到 wholeNumber
wholeNumber += currentChar;
// 4.3.2 若expression已经到达末尾 或者 expression的下一字符为 运算符:将wholeNumber入数字栈,并清空wholeNumber
if (i == expression.length() - 1 || ArrayStack2.isValidOperator(expression.charAt(i + 1))){
digitStack.push(Integer.parseInt(wholeNumber));
wholeNumber = "";
}
// 4.3.3 判断前一运算符是否为'/',若是,先计算,并将结果放入数字栈
if (!operatorStack.isEmpty() && operatorStack.peekTop() == '/') {
operatorStack.pop();
number1 = digitStack.pop();
number2 = digitStack.pop();
result = number2 / number1;
digitStack.push(result);
}
// 4.3.4 否则继续遍历expression
}
}
// 5. expression 扫描完毕,依次pop出两个栈的数字和运算符,计算结果,当运算符栈为空时停止
while (!operatorStack.isEmpty()) {
// 5.1 数字栈取两个数字,取出栈顶字符,计算出结果
number1 = digitStack.pop();
number2 = digitStack.pop();
operator = operatorStack.pop();
// 5.2 两个字符同级,若前一个字符为"-",则改当前字符为同级的另一字符
if (!operatorStack.isEmpty()) {
operator = ArrayStack2.changeOperator(operator, operatorStack.peekTop());
}
// 5.3 计算结果
result = ArrayStack2.calculator(number1, number2, operator);
// 5.4 结果入数字栈
digitStack.push(result);
}
// 6. 返回数字栈剩余的那个数字
return digitStack.pop();
}
}
2. 栈(为计算器服务)
class ArrayStack2 {
private int maxSize;
private int[] array;
private int top = -1;
public ArrayStack2(int maxSize) {
this.maxSize = maxSize;
this.array = new int[maxSize];
}
public boolean isFull() {
return this.top == this.maxSize - 1;
}
public boolean isEmpty() {
return this.top == -1;
}
public void push(int data) {
if (this.top == this.maxSize - 1) {
throw new RuntimeException("full");
}
this.top++;
this.array[top] = data;
}
public int pop() {
if (this.top == -1) {
throw new RuntimeException("empty");
}
int tempData = this.array[this.top];
this.array[this.top] = 0;
this.top--;
return tempData;
}
public int getLength() {
int count = 0;
for (int i = this.top; i >= 0; i--) {
count++;
}
return count;
}
public void displayAllDataFromTop() {
if (this.top == -1) {
throw new RuntimeException("empty");
}
for (int i = this.top; i >= 0; i--) {
System.out.printf("array[%d] -> %d\n", i, this.array[i]);
}
}
/**
* 返回运算符的优先级
* * 和 / 是第一高,返回1
* + 和 - 是第二高,返回10
* 非法字符,返回-1
* @param operator - 输入的运算符
* @return - 运算符优先级的数字级别
*/
public static int operatorPriority(int operator) {
if (operator == '*' || operator == '/') {
return 1;
} else if (operator == '+' || operator == '-') {
return 0;
} else {
return -1;
}
}
/**
* 判断是否是运算符
* @param operator - 要判断的运算符
* @return - true合法,false非法
*/
public static boolean isValidOperator(int operator) {
return operator == '+' || operator == '-' || operator == '*' || operator == '/';
}
/**
* 判断是否是数字
* @param number - 要判断的运算符
* @return - true合法,false非法
*/
public static boolean isValidNumber(int number) {
return number == '0'
|| number == '1'
|| number == '2'
|| number == '3'
|| number == '4'
|| number == '5'
|| number == '6'
|| number == '7'
|| number == '8'
|| number == '9';
}
/**
* 通过所给的运算符,计算所给的两个数
* @param num1
* @param num2
* @param operator
* @return - 计算结果
*/
public static int calculator(int num1, int num2, int operator) {
int result = 0;
switch (operator) {
case '+':
result = num1 + num2;
break;
case '-':
result = num2 - num1;
break;
case '*':
result = num1 * num2;
break;
case '/':
result = num2 / num1;
break;
default:
break;
}
return result;
}
/**
* 若前一个字符为"-",则改当前字符为同级的另一字符
* @param currentOperator - 当前字符
* @param preOperator - 前一个字符
* @return - 返回更改后的字符
*/
public static int changeOperator(int currentOperator, int preOperator) {
if (preOperator == '-' && currentOperator == '-') {
currentOperator = '+';
} else if (preOperator == '-' && currentOperator == '+') {
currentOperator = '-';
}
return currentOperator;
}
/**
* 查看栈顶的值
* @return - 栈顶值
*/
public int peekTop() {
return this.array[top];
}
}