思路分析:
代碼實現:
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; } }