數據結構之中綴表達式實現計算器


棧還是用的上一篇的數組模擬棧,並在此之上增加了

判斷是否是一個運算符的方法

獲取運算符的優先級方法

計算結果方法

查看棧頂元素的方法

四個方法,具體代碼如下:

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());

    }

}

 


免責聲明!

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



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