栈实现综合计算器
思路分析:
代码实现:
package stack; public class Calculator { public static void main(String[] args) { String expression="7+2*60-4";//如何处理多位数的问题? //创建两个栈,一个数栈,一个符号栈 ArrayStack2 numStack= new ArrayStack2(10); ArrayStack2 operStack = new ArrayStack2(10); //定义相关变量 int index=0;//用于扫描 int num1=0; int num2=0; int oper=0; int res=0; char ch=' ';//将每次扫描得到char保存到ch String keepNum=""; //开始while循环扫描expression while(true) { //以此得到expression的每一个字符 ch=expression.substring(index,index+1).charAt(0); //判断ch if(operStack.isOper(ch)) { //判断当前符号栈是否为空 if(!operStack.isEmpty()) { //如果符号栈有操作符,就进行比较,如果当前的操作符优先级小于或者等于栈中的操作 if(operStack.priority(ch)<=operStack.priority(operStack.peek())){ num1=numStack.pop(); num2=numStack.pop(); oper=operStack.pop(); res=numStack.cal(num1, num2, oper); //把运算结果入数栈 numStack.push(res); //把当前的操作符入符号栈 operStack.push(ch); }else { //直接入栈 operStack.push(ch); } }else { //如果为空,直接入符号栈 operStack.push(ch); } }else { //如果是数栈,则直接入数栈 //当处理多位数时。不能发现是一个数就立即入栈 //在处理时,需要向expression的表达式的index后再看一位,如果是数,就进行扫描,如果是·符号才入栈 //因此我们需要定义一个变量字符串,用于拼接 keepNum+=ch; //如果ch已经是expression最后一位 if(index==expression.length()-1) { numStack.push(Integer.parseInt(keepNum)); }else { //判断下一个字符是不是数字 if(operStack.isOper(expression.substring(index+1,index+2).charAt(0))) { //如果后一位是运算符,则入栈 numStack.push(Integer.parseInt(keepNum)); keepNum=""; } // numStack.push(ch-48); } } //让index+1,并判断是否扫描到expression最后 index++; if(index>=expression.length()) { break; } } while(true) { //如果符号栈为空,则计算到最后的结果 if(operStack.isEmpty()) { break; }num1=numStack.pop(); num2=numStack.pop(); oper=operStack.pop(); res=numStack.cal(num1, num2, oper); numStack.push(res); } System.out.printf("表达式%s=%d",expression,numStack.pop()); } } //先创建一个栈,需要扩展功能 class ArrayStack2{ private int maxSize; private int[] stack;//数组模拟栈,数据就放在该数组 private int top=-1; //构造器 public ArrayStack2(int maxSize) { this.maxSize=maxSize; stack=new int[this.maxSize]; } //增加一个方法,可以返回当前栈顶的值但是不pop public int peek() { return stack[top]; } //栈满 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++; stack[top]=value; } //出栈 public int pop() { if(isEmpty()) { //抛异常处理 throw new RuntimeException( "栈空,没有数据"); } int value=stack[top]; 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]); } } //返回运算符的优先级,优先级是程序员来确定的,优先级使用数字表示,数字越大,优先级越高 public int priority(int oper) { if(oper=='*'||oper=='/') { return 1; }else if(oper=='+'||oper=='-') { return 0; }else { return -1;//假定目前表达式只有加减乘除 } } //判断是不是运算符 public boolean isOper(char val) { return val=='+'||val=='-'||val=='*'||val=='/'; } //计算方法 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; default: break; } return res; } }