用栈完成计算一个表达式
思路:
- 通过一个index值(索引),来遍历我们的表达式
- 如果发现是一个数字,直接入栈
- 如果发现扫描到是一个符号,分情况讨论:
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.println(calc.calc(str));
}
}
class StackCalculator{
// private String expression; //字符串表达式
// public StackCalculator(String expression) {
// this.expression=expression;
// }
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;
}
}
}
运行结果