使用数据结构栈实现表达式计算器
思维导图:
代码实现:
重在学习锻炼思维:
package com.Exercise.DataStructure_Algorithm.Stack; public class Calculator { public static void main(String[] args) { String s= "5*2-1"; ArrayStack2 numberStack = new ArrayStack2(10); ArrayStack2 OperatorStack = new ArrayStack2(10); int index = 0; //扫描索引 int num1 = 0; int num2 = 0; int operator = 0; //数据保存 int res = 0; String text = ""; char ch = ' ';//扫描到的结果 while(true){ ch = s.substring(index,index+1).charAt(0); //判断是否是操作符运算符 if(OperatorStack.isOperator(ch)){ //判断操作符栈是否为空 /* * 思路: 4.1.此时时判断当前即将入栈的操作符是否大于还是小于已经进入的操作符, 如果大于栈中的操作符级别,就直接入栈。 4.2.如果即将入栈的操作符级别小于或者等于栈中的操作符,就先进行栈中操作符的运算, 从数字栈中pop出两个数字,再从操作符栈中pop出一位操作符出来,进行运算后, 然后将新扫描的操作符入栈,然后把新运算出来的结果放入数字栈 * * * */ if(!OperatorStack.isNull()){ //如果不为空,继续判断 //如果当前扫描到的操作运算符的值<=栈中的操作符运算符 if(OperatorStack.OperatorPriority(ch) <= OperatorStack.OperatorPriority(OperatorStack.getValue())){ num1 = numberStack.pop(); num2 = numberStack.pop(); operator = OperatorStack.pop(); res = numberStack.cal(num1, num2, operator); numberStack.push(res); OperatorStack.push(ch); }else{ OperatorStack.push(ch); } }else{ //如果为空直接入栈 OperatorStack.push(ch); } //如果不是操作运算符的话 }else{ //处理多位数字 //如果是50*2-1 //ch是ascii码,要把它还原成数字 //拼接 text += ch; // System.out.println(text); //如果索引指向的的数据的位置是最后一位数字,那么就直接入栈 if(index == s.length()-1){ numberStack.push(Integer.parseInt(text)); }else { //判断下一个数是否是操作运算符,如果是,那就入数栈,如果不是操作运算符,回去继续拼接 if (OperatorStack.isOperator(s.substring(index + 1, index + 2).charAt(0))) { numberStack.push(Integer.parseInt(text)); text = ""; } } } index++; // System.out.println(index); if(index >= s.length()){ break; } } //当表达式扫描完毕之后,pop出数栈中的数字和pop出操作符栈的操作符,进行运算 while(true) { //如果操作运算符栈为空 if (OperatorStack.isNull()) { break; } num1 = numberStack.pop(); num2 = numberStack.pop(); operator = OperatorStack.pop(); res = numberStack.cal(num1, num2, operator); numberStack.push(res); } int value = numberStack.pop(); System.out.printf("表达式%s的内容是%d",s,value); } } //数组模拟栈 class ArrayStack2{ //栈顶 private int top = -1; private int maxSize; private int[] arrayStack; public ArrayStack2(int maxSize){ this.maxSize = maxSize; arrayStack = new int[maxSize]; } //栈是否满 public boolean isFull(){ return top == maxSize-1; } //栈是否为空 public boolean isNull(){ return top == -1; } /* * [3] top=2 * [2] top=1 * [1] top=0 * top=-1 * * * */ //入栈 public void push(int data){ if(isFull()){ System.out.println("已经满了,无法入栈了"); return; } top++; arrayStack[top] = data; } //出栈 public int pop(){ if(isNull()){ throw new RuntimeException("栈数据不能为空"); } int value = arrayStack[top]; top--; return value; } //显示栈数据 public void list(){ if(isNull()){ System.out.println("栈数据为空,无法显示栈数据"); return; } for(int i=top;i>=0;i--){ System.out.printf("arrayStack[%d]=%d",i,arrayStack[i]); } } //返回栈中的数据 public int getValue(){ return arrayStack[top]; } //设置操作运算符符优先级 public int OperatorPriority(int value){ if(value == '*' || value == '/'){ return 1; }else if(value == '+' || value == '-'){ return 0; }else{ return -1; } } //判断是不是操作运算符 public boolean isOperator(char value){ return value == '+' || value =='-' || value == '*' || value == '/'; } //计算方法 public int cal(int num1,int num2,int oper){ //存储运算结果 int res = 0; switch (oper){ case '+': res = num1+num2; break; case '-': res = num2-num1; break; case '*': res = num1*num2; break; case '/': res = num2/num1; break; } return res; } }
运行结果:
参考:韩顺片java数据结构和算法