public class CalculateDemo {
/*
使用栈计算表达式的结果。表达式只含有数字(0-9)和加减乘除符号
3+2*6-2 = 11
步骤:1. 遍历表达式
2. 如果是数字,直接入数栈
3. 如果是符号:
3.1. 若当前符号栈为空,则直接入栈
3.2. 若当前符号栈有操作符,就比较
a. 若当前操作符 优先级 <= 栈顶操作符,则 pop 处两个数,pop1 个操作符,进行运算,结果入数栈,当前操作符入符号栈
b. 若当前操作符 优先级 > 栈顶操作符,则当前操作符入符号栈
4. 表达式扫描完毕,就顺序从符号栈和数字栈 pop,并运算,结果 push 进数栈
5. 最后在数栈中只有一个数字,就是表达式的结果
*/
public double calculate(String exp) {Stack<Character> opStack = new Stack();
Stack<Double> numStack = new Stack();
for (int i = 0; i < exp.length(); i++) {char c = exp.charAt(i);
if (isOp(c)) { // 操作符
if (opStack.isEmpty()) opStack.push(c);
else {
// 若当前操作符 c 优先级 <= 栈顶操作符
if (priority(c) <= priority(opStack.peek())) {double n1 = numStack.pop();
double n2 = numStack.pop();
char op = opStack.pop();
double res = calculate(n2, n1, op);
// pop 两个数字和一个操作符(注意顺序)计算结果入栈 并把当前操作符入栈
numStack.push(res);
opStack.push(c);
} else {
// 否则直接把当前操作符入栈
opStack.push(c);
}
}
} else { // 是数字
int cur = c - '0';
numStack.push((double)cur);
}
}
// 现在栈中存放的都是优先级一样的操作符,按 pop 顺序进行计算,结果入栈
while (!opStack.isEmpty()) {char op = opStack.pop();
double n1 = numStack.pop();
double n2 = numStack.pop();
double res = calculate(n2, n1, op);
numStack.push(res);
}
// 最终数字栈剩余一个数字,就是表达式的最终结果
return numStack.pop();}
public double calculate(double a, double b, char c) {if (c == '+') return a + b;
if (c == '-') return a - b;
if (c == '*') return a * b;
if (c == '/') return a / b;
throw new RuntimeException("invalid input");
}
public boolean isOp(char c) {return c == '+' || c == '-' || c == '*' || c == '/';}
public int priority(char c) {if (c == '+' || c == '-') return 1;
if (c == '*' || c == '/') return 2;
return -1;
}
public static void main(String[] args) {
String exp = "3+2*6-2";
String exp1 = "7*2*2-5+1-5+3-4";
CalculateDemo app = new CalculateDemo();
System.out.println(app.calculate(exp));
System.out.println(app.calculate(exp1));
}
}