棧實現綜合計算器


思路分析:

 

 代碼實現:

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;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM