回顧數據結構(Java版)——中綴表達式實現簡單計算器

自定義棧並且使用中綴表達式實現計算器,代碼中有幾個比較容易出錯的點,比如多位數的情況,longNumber的清空等等

package com.wrial.calculator;
/*
 * @Author  Wrial
 * @Date Created in 11:53 2019/10/10
 * @Description 使用棧實現單值計算器(中綴表達式)
 */


public class Calculator {

    public static void main(String[] args) {
        String aimStr = "10+6/2+5*2";
        int index = 0;//記錄分解字符串當前位置
        char anChar; //記錄aimStr分解後的單個字符
        int num1;//進行計算的數字1
        int num2;//進行計算的數字2
        int result;//計算的結果
        char operator;//進行計算的操作符
        String longNumber = "";


        Calculator calculator = new Calculator();
        //1.創建兩個棧(數字棧和操作符棧)
        ArrayStack numberStack = new ArrayStack<Integer>();
        ArrayStack operatorStack = new ArrayStack<Character>();
        //2.分解字符串並對應入棧
        for (index = 0; index < aimStr.length(); index++) {
            anChar = aimStr.substring(index, index + 1).charAt(0);
            //3.如果是一個操作符就判斷優先級而看是否要進行入棧
            if (calculator.isOperator(anChar)) {
                //4.如果操作棧是空的,那就直接入棧
                if (operatorStack.isEmpty()) {
                    operatorStack.push(anChar);
                    //5.如果操作棧不爲空,就和前面的操作符號比較優先級(如果當前操作符優先級小於棧頂操作符就出棧計算)
                } else if (calculator.operatorPrivilege((char) operatorStack.peek())
                        >= calculator.operatorPrivilege(anChar)) {
                    //6.從數字棧中出兩個,從符號棧中出一個
                    num1 = (int) numberStack.pop();
                    num2 = (int) numberStack.pop();
                    operator = (char) operatorStack.pop();
                    result = calculator.calculate(num1, num2, operator);
                    System.out.println(num1 + operator + num2 + " = " + result);
                    //7.計算完後將結果放入數字棧
                    numberStack.push(result);
                    //8.將當前操作符放入操作符棧
                    operatorStack.push(anChar);
                    //9.如果優先級大於棧頂就入棧
                } else {
                    operatorStack.push(anChar);
                }
            } else {
                longNumber += anChar;
                //10.如果index到最後了,就把它入數棧,如果對它進行判斷下一個是不是操作符就會出現越界異常
                if (index == aimStr.length() - 1) {
                    numberStack.push(Integer.parseInt(longNumber));
                    //入棧後必須清空
                    longNumber = "";
                    //11.如果下一個是操作符就得將這個數字串入棧
                } else if (calculator.isOperator(aimStr.substring(index + 1, index + 2).charAt(0))) {
                    numberStack.push(Integer.parseInt(longNumber));
                    //在入棧後必須要清空
                    longNumber = "";
                }
            }
        }
        //12.到此,數據掃描階段就過去了,開始正式的計算階段,直至運算符棧空
        while (true) {

            if (operatorStack.isEmpty()) {
                System.out.println("計算結束,結果=" + numberStack.peek());
                break;
            } else {
                num1 = (int) numberStack.pop();
                num2 = (int) numberStack.pop();
                operator = (char) operatorStack.pop();
                result = calculator.calculate(num1, num2, operator);
                System.out.println(num1 + operator + num2 + " = " + result);
                //計算完後將結果放入數字棧
                numberStack.push(result);
            }
        }


    }

    /*
       如果是加減乘除就返回true
       */
    public boolean isOperator(char operator) {
        switch (operator) {
            case '*':
            case '-':
            case '/':
            case '+':
                return true;
        }
        return false;
    }

    /*
    這裏注意的一點就是先入棧的數是後出棧的,因此要將前後反過來
     */
    public int calculate(int num1, int num2, char operator) {
        switch (operator) {
            case '*':
                return num2 * num1;
            case '-':
                return num2 - num1;
            case '/':
                return num2 / num1;
            case '+':
                return num2 + num1;
        }
        System.err.println("不存在此操作");
        return -1;
    }

    /*
    因爲操作符入棧的時候要判斷等級,如果優先級大於或者等於就入棧,否則就出棧
     */
    public int operatorPrivilege(char operator) {
        if (operator == '*' || operator == '/') {
            return 2;
        }
        if (operator == '+' || operator == '-') {
            return 1;
        }
        System.err.println("暫不支持此操作符");
        return -1;
    }

}

interface Stack<T> {
    /**
     * 棧是否爲空
     */
    boolean isEmpty();

    /**
     * data元素入棧
     */
    void push(T data);

    /**
     * 返回棧頂元素,未出棧
     */
    T peek();

    /**
     * 出棧,返回棧頂元素,同時從棧中移除該元素
     */
    T pop();

    /**
     * 是否棧滿
     */
    boolean isFull();

    /**
     * 遍歷棧
     */
    void showAll();
}

class ArrayStack<T> implements Stack {
    private T[] array;
    private int capacity;
    private int top = -1;  //棧頂初始化爲-1

    ArrayStack(int capacity) {
        this.capacity = capacity;
        array = (T[]) new Object[capacity];
    }

    ArrayStack() {
        this.capacity = 16;
        array = (T[]) new Object[16];
    }


    @Override
    public boolean isEmpty() {
        return top == -1;
    }

    @Override
    public void push(Object data) {
        if (isFull()) {
            System.out.println("棧滿");
            return;
        }
        top++;
        array[top] = (T) data;
        System.out.println("入棧成功" + array[top]);

    }

    @Override
    public Object peek() {
        return array[top];
    }

    public T pop() {
        if (isEmpty()) {
            System.out.println("棧空");
            return null;
        } else {
            T value = array[top];
            top--;
            System.out.println("出棧成功" + value);
            return value;
        }
    }

    @Override
    public boolean isFull() {
        return top == capacity;
    }

    //記得遍歷棧的時候是從上往下遍歷
    @Override
    public void showAll() {
        for (int i = top; i >= 0; i--) {
            System.out.printf("%d\t", array[i]);
        }
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章