栈还是用的上一篇的数组模拟栈,并在此之上增加了
判断是否是一个运算符的方法
获取运算符的优先级方法
计算结果方法
查看栈顶元素的方法
四个方法,具体代码如下:
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()); } }