JAVA如何利用動態數組將數學中綴表達式轉化後綴表達式(逆波蘭)的思想並計算

關於計算數學表達式的方法有很多種,一般人們習慣是用中綴表達式去寫,而計算機並不能很好理解與計算,計算起來也很麻煩,如何去寫呢?

Calculator.java-CSDN下載 https://download.csdn.net/download/weixin_44688297/11897934

在這裏我只會寫我的算法以及思想,代碼已經發出來。還有如何轉化成後綴表達式,這裏不會細說,有時間我再補。

先說一下爲什麼要用動態數組呢?爲什麼不用棧?因爲我有一個對負號特殊的處理,動態數組的好處是我可以隨便指定一個位置進行插入,方法很簡單。

算法思想:利用動態數組實現棧。
1.先將表達式中的特殊的負號(將每一個左括號(前面的負號)轉化成減號,再其前面加上一個0,因爲這樣就可以區分負號和減號。例如:18/48-(-(4+5))將這種類型轉化成18/48-(0-(4+5))然後將其計算,因爲我的算法裏面不能對-(這種情況的負號進行區分,所以就想到了這種方法,爲什麼不寫算法去區分呢?因爲這種情況你根本無法預知會出現多少次,所以循環的判斷語句無法寫,我還不如直接對這種特殊的情況處理。
代碼:

//這裏的代碼需要自己處理,後面我會將完整的代碼全部發出,計算的也會發
ArrayList<Character>epress = new ArrayList<Character>();//對負號處理是動態數組
//18/48-(-(4+5))將這種類型轉化成18/48-(0-(4+5))然後將其計算
        for (int i = 0; i < expression.length(); i++) {
            char a = expression.charAt(i);
            epress.add(a);
        }
        boolean v = true;
        int k = 0;
        while (v){
            if (epress.get(k) == '-' && k == 0){
                if (epress.get(k + 1) == '(') {
                    epress.add(0, '0');
                    k += 3;//向後移動三位0(-,移動到下一個運算符
                }else {
                    v = false;
                }
            }else if (epress.get(k) == '-' && epress.get(k-1) == '('){
                epress.add(k,'0');
                k += 3;//向後移動三位0(-,移動到下一個運算符
            }else {
                k++;
            }
            if (k == epress.size()){
                v = false;
            }
        }
        expression = "";//令表達式爲空,然後依次將對負號處理完的動態epress裏面的內容重新賦給表達式
        for (int i = 0; i < epress.size(); i++) {
            expression += epress.get(i);
        }
        

中綴轉化後綴表達式

	ArrayList operand = new ArrayList();//操作數動態數組
    ArrayList<Character> operator = new ArrayList<Character>();//運算符動態數組
    ArrayList<Character>epress = new ArrayList<Character>();//對負號處理是動態數組
//以下是計算表達式轉化成後綴表達式
        String expre = "";//存實數
        for (int i = 0; i < expression.length(); i++) {
            char a = expression.charAt(i);
            if (a == '-') {
                if (i > 0) {
                    if (expression.charAt(i-1) == '(') {//括號後面是負數的處理
                        expre += a;
                    }
                    else {
                        if (!"".equals(expre)) {//如果不爲空
                            double num = Double.valueOf(expre);
                            operand.add(num);
                            expre = "";
                        }
                        int length = operator.size();
                        if (length >= 1 ) {//-符號壓棧與出棧
                            if (operator.get(length - 1) == '+' || operator.get(length - 1) == '-') {
                                operand.add(operator.get(length - 1));
                                operator.remove(length - 1);
                            }else if (operator.get(length - 1) == '*' || operator.get(length - 1) == '/'){
                                int size = operator.size();
                                while (size > 0) {//取棧
                                    if (operator.get(size - 1) != '(') {
                                        operand.add(operator.get(size - 1));
                                    }
                                    operator.remove(size - 1);
                                    size--;
                                }
                                operator.add(a);
                                continue;
                            }
                        }
                        operator.add(a);
                    }
                }else {
                    expre += a;
                }
            } else if ((a <= '9' && a >= '0') || a == '.') {
                    expre += expression.charAt(i);
                    if (i == expression.length() - 1) {//最後一個爲數字
                        double num = Double.valueOf(expre);
                        operand.add(num);
                        expre = "";
                    }
            } else {
                if (!expre.equals("")) {
                    double num = Double.valueOf(expre);
                    operand.add(num);
                    expre = "";
                }
                int size = operator.size();
                if (size == 0 || a == '(') {//運算符棧爲空
                    operator.add(a);
                } else if (a != ')') {
                    if (operator.get(size - 1) == '(') {
                        operator.add(a);//壓棧
                    } else if (operator.get(size - 1) == '*' || operator.get(size - 1) == '/') {
                        if (a == '+' ) {//取棧並壓棧
                            while (size > operator.lastIndexOf('(') + 1) {
                                if (operator.get(size - 1) != '(') {
                                    operand.add(operator.get(size - 1));
                                }
                                operator.remove(size - 1);
                                size--;
                            }
                            operator.add(a);
                        } else {
                            operand.add(operator.get(size - 1));
                            operator.remove(size - 1);
                            operator.add(a);
                        }
                    } else if (operator.get(size - 1) == '+' || operator.get(size - 1) == '-') {
                        if (a == '+' ) {//取棧並壓棧
                            while (size > operator.lastIndexOf('(') + 1) {
                                if (operator.get(size - 1) != '(') {
                                    operand.add(operator.get(size - 1));
                                }
                                operator.remove(size - 1);
                                size--;
                            }
                            operator.add(a);
                        } else {//壓棧
                                operator.add(a);
                            }
                        }
                } else  {//取棧
                    while (size > operator.lastIndexOf('(') + 1) {
                        if (size - 1 >= 0) {
                            operand.add(operator.get(size - 1));
                            operator.remove(size - 1);
                        }
                        size--;
                    }
                    if (size > 0) {
                        operator.remove(size - 1);
                    } else if (size == 0) {
                        operator.remove(0);
                    }
                }
            }
        }
        //如果operator裏面還有運算符,就將其弄到後綴表達式的最後
        int size = operator.size();
        while (size > 0){
            operand.add(operator.get(size-1));
            operator.remove(size-1);
            size--;
        }
        System.out.println(operand);//輸出已經轉好的後綴表達式
        }
2.將處理後的表達式轉化成後綴表達式(逆波蘭表達式)
用棧的思想以及動態數組,
3.計算後綴表達式(逆波蘭表達式)
//找到最早出現的一個運算符,然後取其前面兩個數字進行運算

//後綴表達式計算算法演示
*[-2.5, 3.2, -5.0, 4.0, +, , 3.0, /, -2.0, /, 9.0, , +]
[-2.5, 3.2, -5+4, * , 3.0, /, -2.0, /, 9.0, , +]
[-2.5, 3.2
(-5+4) , 3.0 /, -2.0, /, 9.0, , +]
[-2.5, 3.2
(-5+4), -2.0 /, 9.0, , +]
[-2.5, 3.2
(-5+4)/3.0/-2.0 , 9.0, , +]
[-2.5, 3.2
(-5+4)/3.0/-2.0
9.0, +]

如果大家需要更加多功能計算表達式的話,我後面還寫了一個有三角函數,有ln,log,次方的,需要的話私聊我。。

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