用栈完成计算一个表达式
思路:
- 遍历我们的表达式
- 如果发现是数字,入栈
- 如果是一个运算符,分情况讨论:
3.1 如果发现当前的符号栈为空,直接入栈
3.2 如果符号栈有操作符,就先进行比较,
如果当前操作符的优先级小于或者等于栈中的操作符,
从数栈中pop出两个数,再从符号栈中pop出一个符号,进行计算,然后将当前的操作符入栈,如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈。 - 当表达式扫描完毕,就顺序从数栈和符号栈中pop出相应的数和符号,并运行。
- 最后在数栈只有一个数字,就是表达式的结果。
仅支持整数运算
package com.psyche.calculator;
import java.util.Stack;
public class StackCalculatorDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
StackCalculator calc = new StackCalculator();
String str = "1+2*3-6/2";
System.out.printf("%s = %d", str, calc.calc(str));
}
}
class StackCalculator {
private Stack<Integer> numStack;
private Stack<Character> operStack;
private char[] exp;
// 操作符的优先级 (* /) > (+ -)
public int calc(String expression) {
exp = new char[expression.length()]; // 字符数组 存放表达式
exp = expression.toCharArray();
numStack = new Stack<Integer>(); // 数字栈
operStack = new Stack<Character>(); // 操作符栈
// 遍历字符数组
for (int i = 0; i < exp.length; i++) {
// 判断该字符是数字还是操作符
if (exp[i] >= '0' && exp[i] <= '9') { // 数字
numStack.push(Integer.valueOf(exp[i] - 48));
} else if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') { // 运算符
char val = exp[i];
switch (val) {
// 符号:
// +----------------------------------------------------------------------------------------------------------------
case '+':
// 1.判断符号栈是否为空,空直接入符号栈
if (operStack.isEmpty()) {
operStack.push(val);
} else {
pushAndCalc(operStack.pop());
operStack.push(val);
}
break;
// 符号: -
// -----------------------------------------------------------------------------------
case '-':
// 1.判断符号栈是否为空,空直接入符号栈
if (operStack.isEmpty()) {
operStack.push(val);
} else {
pushAndCalc(operStack.pop());
// 符号压栈
operStack.push(val);
}
break;
// 符号: *
// -------------------------------------------------------------------------------------------
case '*':
// 1.判断符号栈是否为空,空直接入符号栈
if (operStack.isEmpty()) {
operStack.push(val);
} else {
// 判断
if (operStack.peek() == '+' || operStack.peek() == '-') {
operStack.push('*');
} else {
pushAndCalc(operStack.pop());
// 符号压栈
operStack.push(val);
}
}
break;
// 符号: /
// --------------------------------------------------------------------------------------------------
case '/':
// 1.判断符号栈是否为空,空直接入符号栈
if (operStack.isEmpty()) {
operStack.push(val);
} else {
// 判断
if (operStack.peek() == '+' || operStack.peek() == '-') {
operStack.push('/');
} else {
pushAndCalc(operStack.pop());
// 符号压栈
operStack.push(val);
}
}
break;
default:
break;
}
} else {
throw new RuntimeException("表达式存在非法字符"); // 非法字符
}
}
// 遍历之后若符号栈不为空,弹出所有符号
while (!operStack.isEmpty()) {
pushAndCalc(operStack.pop());
}
return numStack.pop();
}
public void pushAndCalc(char oper) { // 根据运算符进行运算,自动从数据栈中去数据。
int val1 = numStack.pop();
int val2 = numStack.pop();
switch (oper) {
case '+':
numStack.push(val2 + val1);
break;
case '-':
numStack.push(val2 - val1);
break;
case '*':
numStack.push(val2 * val1);
break;
case '/':
numStack.push(val2 / val1);
break;
}
}
}
运行结果