支持加减乘除及括号运算
public class Calculator {
private static final char ADD_OPER = '+';
private static final char SUB_OPER = '-';
private static final char MUL_OPER = 'x';
private static final char DIV_OPER = '/';
private static final char LEFT_OPER = '(';
private static final char RIGHT_OPER = ')';
private static final String suffix = "+0";
public static void main(String[] args) {
Calculator calculator = new Calculator();
System.out.println(calculator.cal("0-2x3+5")); // -1
System.out.println(calculator.cal("2-8x6/4")); // -10
System.out.println(calculator.cal("-23+48x7-(8+78x9/3)+8/4-8"));//65
}
public int cal(String expression) {
// 处理表达式
expression = handleExpression(expression);
LinkedList<Integer> numStack = new LinkedList<>(); //数字栈
LinkedList<Character> operStack = new LinkedList<>(); //符号栈
int index = 0; // 指针,指向表达式的位置
String num = ""; // 处理多位数
while (true) {
char ch = expression.charAt(index);
if (isOper(ch)) { // 运算符
// 符号栈不为空,且栈顶运算符为乘/除,计算乘除值
if (!operStack.isEmpty() && priority(operStack.peekLast()) == 1) {
int calVal = calculate(numStack.removeLast(), numStack.removeLast(), operStack.removeLast());
numStack.addLast(calVal);
}
operStack.addLast(ch);
index++;
} else if (isParentheses(ch)) { // 括号
int begin = index, end = index;
while (expression.charAt(index) != RIGHT_OPER) {
index++;
}
end = index;
// 计算括号里的表达式
int cal = cal(expression.substring(begin + 1, end));
numStack.addLast(cal);
index++;
} else { // 数字
num = num + ch;
// 到达表达式结尾,结束循环
if (index == expression.length() - 1) {
numStack.addLast(Integer.parseInt(num));
break;
}
// 下一位不是数字,将当前值压如数字栈
if (!isNumber(expression.charAt(index + 1))) {
numStack.addLast(Integer.parseInt(num));
num = "";
}
index++;
}
}
// 从前往后遍历,进行加/减运算,此时符号栈只有加/减
int calVal = numStack.remove();
while (!operStack.isEmpty()) {
calVal = calculate(calVal, numStack.remove(), operStack.remove().charValue());
}
return calVal;
}
private String handleExpression(String expression) {
char ch = expression.charAt(0);
if (ch == ADD_OPER || ch == SUB_OPER) { // 防止表达式首字符为运算式
expression = "0" + expression;
}
expression = expression + suffix; // 防止 4+5/2,会先计算4+5
return expression;
}
/**
* 加减乘除的优先级
* @param oper 运算符
* @return
*/
private int priority(char oper){
if(oper == MUL_OPER || oper == DIV_OPER){
return 1;
}else if(oper == ADD_OPER || oper == SUB_OPER){
return 0;
}else {
return -1;
}
}
/**
* 乘除按出栈顺序进行运算,加减按出队列顺序计算
* @param num1
* @param num2
* @param oper
* @return
*/
private int calculate(int num1, int num2, char oper){
int result = 0;
switch (oper){
case ADD_OPER:
result = num1 + num2;
break;
case SUB_OPER:
result = num1 - num2;
break;
case MUL_OPER:
result = num1 * num2;
break;
case DIV_OPER:
result = num2 / num1;
break;
default:
break;
}
return result;
}
/**
* 当前字符是否为数字
* @param ch
* @return
*/
private boolean isNumber(char ch) {
if (ch >= '0' && ch <= '9') {
return true;
}
return false;
}
/**
* 是否为运算符
* @param ch 运算符
* @return
*/
private boolean isOper(char ch) {
return ch == ADD_OPER || ch == SUB_OPER || ch == MUL_OPER || ch == DIV_OPER;
}
/**
* 是否为括号
* @param ch
* @return
*/
private boolean isParentheses(char ch){
return ch == LEFT_OPER || ch == RIGHT_OPER;
}
}