栈还是用的上一篇的数组模拟栈,并在此之上增加了
判断是否是一个运算符的方法
获取运算符的优先级方法
计算结果方法
查看栈顶元素的方法
四个方法,具体代码如下:
package com.ebiz.stack;/*** @author YHj* @create 2019-07-20 14:20* 数组模拟栈*/public class ArrayStack {private int maxSize;private int [] arr; //数组模拟栈 private int top = -1;//构造方法,初始化数组public ArrayStack(int maxSize) {this.maxSize=maxSize;this.arr = new int[maxSize];}//验证栈满public boolean isFull(){return top == maxSize-1;}//验证为空public boolean isEmpty(){return top == -1;}//入栈public void push(int value){if (isFull()){System.out.println("栈已满");return;}top++;arr[top]=value;}//出栈public int pop(){if(isEmpty()){throw new RuntimeException("栈已空");}int value=arr[top];top--;return value;}//遍历栈public void list(){if (isEmpty()){throw new RuntimeException("栈为空");}while (true){if (isEmpty()){System.out.println("栈为空");break;}System.out.printf("出站元素为%d%n",arr[top]);top--;}}//返回运算符的优先级 优先级用数字表示//数字越大,代表优先级越高// *或者/ 优先级为1// +或者- 优先级为0// -1 代表运算符为问题运算符public int priority(int operator){if ('*' == operator || '/' == operator){return 1;}else if ('+' == operator || '-' == operator){return 0;}else{return -1;}}//判断是否为一个运算符public boolean isOperator(char operator){return operator == '+' || operator == '-' || operator == '*' || operator == '/';}//计算方法public int calculator(int num01,int num02,int operator){//用于存放计算结果int result=0;switch (operator){case '+':result = num01+num02;break;case '-':result = num02-num01;break;case '*':result = num01*num02;break;case '/':result = num02/num01;break;default:break;}return result;}//获取符号栈的栈顶符号,并不是真正取出该元素public int peek() {return arr[top];} }
下面给出测试,中缀表达式提前给定好,只涉及到了两位数,对于小括号还有小数点后面会将中缀转为后缀,便于计算
package com.ebiz.stack;/*** @author YHj* @create 2019-07-22 11:04* 栈模拟计算器 中缀表达式*/ public class Calculator {public static void main(String[] args) {//表达式//String expression = "50+2*6-2";String expression = "5-2*3+1";//创建数字栈ArrayStack numeStack = new ArrayStack(10);//创建运算符栈ArrayStack operatorStack = new ArrayStack(10);//初始化索引,用于扫描表达式int index = 0;int num01 = 0;int num02 = 0;int operator = ' '; //定义运算符int res =0; //存放结果char ch =' '; //将每次扫描得到的char保存到ch// 定义字符串,拼接多位数String str="";while (true){//开始扫描表达式,并判断是数字还是符号ch=expression.substring(index,index+1).charAt(0);//如果为运算符if (operatorStack.isOperator(ch)){//判断符号栈是否为空 符号栈不为空if (!operatorStack.isEmpty()){//判断符号优先级 当前符号优先级小于或者等于符号栈顶的符号的优先级,//从数字栈弹出两个数字,符号栈弹出栈顶符号,进行计算,结果加入数字栈,当前符号加入符号栈if (operatorStack.priority(ch) <= operatorStack.priority(operatorStack.peek())){num01=numeStack.pop();num02=numeStack.pop();operator=operatorStack.pop();//进行计算res=numeStack.calculator(num01,num02,operator);operatorStack.push(ch);numeStack.push(res);}else { //当前符号的优先级大于符号栈顶的符号的优先级,则直接加入符号栈 operatorStack.push(ch);}}else { //符号栈为空 operatorStack.push(ch);}}else {//不是运算符 直接进入树栈//ASCII表, 查出来的是'1' 对应的十进制为49//numeStack.push(ch-48);//某一字符为多位数时,需要当成字符串处理str+=ch;//判断ch是否为最后一个字符if (index == expression.length()-1){numeStack.push(Integer.parseInt(str));}else {//判断下一位是否是字符,下一位是字符,则将当前拼接字符串存入数字栈if (operatorStack.isOperator(expression.substring(index+1,index+2).charAt(0))){numeStack.push(Integer.parseInt(str));//把str 清空str = "";}}}//继续扫描,索引增加,并判断是否到最后index++;if (index >= expression.length()){break;}}//表达式扫描完毕后,对两个栈中元素进行计算while (true){num01=numeStack.pop();num02=numeStack.pop();operator=operatorStack.pop();numeStack.push(numeStack.calculator(num01, num02, operator));//判断结束if (operatorStack.isEmpty()){break;}}//输出结果System.out.println("result="+numeStack.pop());}}