1 首先分为两个栈:数栈和操作符栈(简称符栈)
2 定义index变量,用于遍历字符串“6+1*2”
3 如果当前遍历的字符是数字,直接入数栈
4 如果当前遍历的字符是操作符,分为两种情况:
4.1 如果符栈为空,直接将操作符放入符栈;
4.2 如果符栈不为空,又分为两种情况:
4.2.1 如果当前操作符A的优先级小于或者等于符栈顶操作符的优先级,则符栈pop出一个操作符B,数栈pop出两个数字,将两个数字按照B操作符进行运算,将运算得到的结果入数栈,并将当前操作符A入符栈。
4.2.2 如果当前操作符A的优先级大于符栈顶操作符的优先级,直接将其入符栈。
5 重复3-4步骤,直到遍历结束
6 此时,从符栈pop出一个操作符,从数栈pop出两个数字,并进行运算,将结果push进数栈
7 重复6步骤,直到符栈为空为止。此时数栈应该有一个数字,即为最终结果。
package stack;
public class Calculator {
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义简单的计算机模型(只包括加减乘除和单数的计算)
//首先定义两个栈:数栈和符栈
ArrayStack2 numsStack = new ArrayStack2(10);
ArrayStack2 opersStack = new ArrayStack2(10);
//定义待运算的字符串
String expression = "70+2*3*6-4";
// String expression = "7+2";
int index = 0;
int num1;
int num2;
int oper;
int res = 0;
String keepNum = "";//用于拼接多位数
char curChar;
//遍历字符串
while(true) {
//遍历字符串,一次得到每个字符
curChar = expression.substring(index, index+1).charAt(0);
//判断是数字还是操作符
if(opersStack.isOper(curChar)) {//是操作符
if(opersStack.isEmpty()) {//符栈是空,直接push操作符
opersStack.push(curChar);
// System.out.println("*********1");
// System.out.println("opersStack入栈:"+curChar);
}else {//符栈不是空,判断当前操作符和栈顶的操作符优先级大小
//如果当前操作符优先级小于或者等于栈顶操作符的优先级,则从数栈中弹出两个数、符栈中弹出一个操作符,做运算
//并将运算结果放在数栈,将当前操作符放在符栈
if(opersStack.privority(curChar) <= opersStack.privority(opersStack.getPeek())) {
num1 = numsStack.pop();
num2 = numsStack.pop();
oper = opersStack.pop();
res = opersStack.calculator(num1, num2, oper);
numsStack.push(res);
opersStack.push(curChar);
// System.out.println("*********2");
// System.out.println("numsStack出栈:"+num1);
// System.out.println("opersStack出栈:"+oper);
// System.out.println("numsStack出栈:"+num2);
// System.out.println("numsStack入栈:"+res);
// System.out.println("opersStack入栈:"+curChar);
}else {//如果当前操作符优先级大于栈顶操作符的优先级,直接入栈
// System.out.println("*********3");
opersStack.push(curChar);
// System.out.println("opersStack入栈:"+curChar);
}
}
}else {//是数字,直接添进数栈
// System.out.println("*********4");
// numsStack.push(curChar - 48);
// System.out.printf("numsStack入栈:%d\n",curChar - 48);
//不能直接入栈,得判断是不是大于一位数的数字
keepNum += curChar;
if(index+1 >= expression.length()) {
numsStack.push(Integer.parseInt(keepNum));
keepNum = "";
}else {
if(opersStack.isOper(expression.subSequence(index+1, index+2).charAt(0))) {
numsStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
}
}
//判断是否遍历结束
index++;
if(index >= expression.length()) {
break;
}
}
//开始计算
while(true) {
// System.out.println("开始计算最终结果");
if(opersStack.isEmpty()) {
break;
}
num1 = numsStack.pop();
num2 = numsStack.pop();
oper = opersStack.pop();
res = opersStack.calculator(num1, num2, oper);
numsStack.push(res);
// System.out.println("num1:"+num1);
// System.out.println("num2:"+num2);
// System.out.println("oper:"+oper);
// System.out.println("res:"+res);
}
res = numsStack.pop();
System.out.printf("运算结果:%s = %d\n",expression,res);
}
}
class ArrayStack2{
private int maxSize;
private int[] stack;
private int top = -1;
public ArrayStack2(int maxSize) {
this.maxSize = maxSize;
stack = new int[maxSize];
}
//判满
public boolean isFull() {
return top == maxSize -1;
}
//判空
public boolean isEmpty() {
return top == -1;
}
//进栈
public void push(int item) {
//判满
if(isFull()) {
System.out.println("栈已满!");
return;
}
stack[++top] = item;
}
//得到操作符的优先级
public int privority( int oper) {
if(oper == '+' || oper == '-') {
return 1;
}else if(oper == '*' || oper == '/') {
return 2;
}else {
throw new RuntimeException("操作符不合理!");
}
}
//判断是否是操作符
public boolean isOper(int oper) {
return oper == '+' || oper == '-' || oper == '*' || oper == '/' ;
}
//得到栈顶的元素
public int getPeek() {
return stack[top];
}
//运算
public int calculator(int num1,int num2,int oper) {
int res = 0;
switch(oper) {
case '+':
// System.out.println("是加");
res = num1 + num2;
break;
case '-':
// System.out.println("是减");
res = num2 - num1;
break;
case '*':
// System.out.println("是乘");
res = num1 * num2;
break;
case '/':
// System.out.println("是除");
res = num2 / num1;
break;
default:
break;
}
return res;
}
//出栈
public int pop() {
if(isEmpty()) {
throw new RuntimeException("栈空!");
}
int value = stack[top--];
return value;
}
//遍历栈(从栈顶到栈底顺序遍历)
public void list() {
if(isEmpty()) {
System.out.println("栈空!");
return;
}
for(int i=top; i>=0; i--) {
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}
}