1. 程式人生 > >字尾表示式轉中綴表示式

字尾表示式轉中綴表示式

大概意思就是:遇到數字就輸出,遇到符號(包括括號)就壓入棧,如果當前符號優先順序比棧頂的低,就把棧頂的符號輸出,平級的也都輸出,到左括號(優先順序最高為止),然後當前符號入棧,如果遇到右括號,就將符號棧頂的符號依次輸出,遍歷完成之後,棧裡的符號依次輸出即可;括號不用輸出;

注:這裡的後轉中,字尾含括號;

package OffLineTest;

/*
* 中綴表示式向後綴表示式的轉換方法:
      規則:從左到右遍歷中綴表示式的每個數字和符號,
      若是數字就輸出,即成為字尾表示式的一部分;
      若是符號,就判斷當前符號與棧頂符號的優先順序,
      如果是右括號或者是優先順序低於棧頂符號(乘除優先加減),
      則棧頂元素依次出棧並輸出(全部輸出,如果是右括號,則到左括號輸出為止),
      當前符號進棧,如此進行直到最終輸出字尾表示式。
* */

/*
輸入字尾表示式:9(31)-3*+12/+
轉為字元陣列:[9, (, 3, 1, ), -, 3, *, +, 1, 2, /, +]
反轉:[+, /, 2, 1, +, *, 3, -, ), 1, 3, (, 9]
存入棧num中的形式:2/1+3*)1-3(+9
輸出中綴表示式:9+(3-1)*3+1/2

* 字尾轉中綴思路:將字尾反轉存為 midReverse陣列,符號存在棧sign中,結果存在棧 num 中,
* 遍歷midReverse ,遇到符號就存入sign ,
* 判斷下個字元是否為左括號')',直接輸入num,(因為括號表示式的第一個括號後面跟的的數字不是符號,但第二個匹配的括號後面跟的是符號,這裡要弄清楚,因為是反序遍歷,然後最終結果是將num的棧頂的元素一個個輸出,所有括號是反的;)
* 遇到數字就存入num,緊接著刪除sign的棧頂元素並存入num(因為中綴表示式為一個數字一個符號的形式),
* 判斷下個字元是否為左括號'(',若是,則將'('存入,並刪除sign的棧頂元素存入num,如例子所示,'2/1+3*)1-3(','('左括號之後應該為‘+’號,如果不設定這個條件,輸出的就是'9'了;
* */

import java.util.*;

public class InfixExpression {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        char[] mid = in.nextLine().toCharArray();
        System.out.println("輸入: "Arrays.toString(mid));
        char[] midReverse = new char[mid.length];
        for (int i = 0; i < mid.length; i++) {
            midReverse[i] = mid[mid.length - 1 - i];
        }
        System.out.println("反轉後: "Arrays.toString(midReverse));

        Stack<Character> sign = new Stack<Character>();
        Stack<Character> num = new Stack<Character>();
        Map<Character, Integer> signMap = new HashMap<Character, Integer>();
        signMap.put('+', 1);
        signMap.put('-', 1);
        signMap.put('*', 2);
        signMap.put('/', 2);

        Character c;
        Character temp;
        for (int i = 0; i < midReverse.length; i++) {
            c = midReverse[i];
            if (signMap.containsKey(c))
                sign.push(c);
            else if ((Character.isDigit(c))) {
//                if (sign.isEmpty()) continue;
                num.push(c);
                if( i == midReverse.length -1) break;
                if(midReverse[i+1] == '(')  {
                    num.push('(');
                    i +=1;
                }
                temp = sign.pop();
                num.push(temp);

            } else if ((c == ')')) {
                num.push(c);
            }
        }

        //output
        System.out.print("中綴表示式:");
        char a;
        int len = num.size();
        for(int i = 0; i < len; i ++){
            a = num.pop();
            System.out.print( a);
        }
    }
}