用棧實現中綴表示式轉字尾表示式
阿新 • • 發佈:2019-02-18
轉換規則:
- 相同等級的運算子,棧外高於棧內。
- 棧外的左括號優先順序最高。
- 棧內的左括號優先順序最低。
- 棧外的右括號優先順序最低。低到和棧內的左括號優先順序一樣。
1.寫一個類用來儲存優先順序,數字越小優先順序越高。
public class Constant { public static final int OPERATORS_PRIO_PLUS_IN = 4; //棧內加法 public static final int OPERATORS_PRIO_SUB_IN = 4; //棧內減法 public static final int OPERATORS_PRIO_MULTY_IN = 2; //棧內乘法 public static final int OPERATORS_PRIO_DIV_IN = 2 ; //棧內除法 public static final int OPERATORS_PRIO_LEFT_BRAK_IN = 10; //棧內左括號 public static final int OPERATORS_PRIO_PLUS_OUT = 5 ; //棧外加法 public static final int OPERATORS_PRIO_SUB_OUT = 5; //棧外減法 public static final int OPERATORS_PRIO_MULTY_OUT = 3; //棧外乘法 public static final int OPERATORS_PRIO_DIV_OUT = 3; //棧外除法 public static final int OPERATORS_PRIO_LEFT_BRAK_OUT = 1; //棧外左括號 public static final int OPERATORS_PRIO_RIGHT_BRAK_OUT = 10; //棧外右括號 public static final int OPERATORS_PRIO_ERROR = -1; }
2.獲取當前運算子的優先順序。
public static int Get_Prio(char opera,boolean instack) { int prio = Constant.OPERATORS_PRIO_ERROR; if(instack) { switch(opera) { case '+': prio = Constant.OPERATORS_PRIO_PLUS_IN; break; case '-': prio = Constant.OPERATORS_PRIO_SUB_IN; break; case '*': prio = Constant.OPERATORS_PRIO_MULTY_IN; break; case '/': prio = Constant.OPERATORS_PRIO_DIV_IN; break; case '(': prio = Constant.OPERATORS_PRIO_LEFT_BRAK_IN; break; default: prio = Constant.OPERATORS_PRIO_ERROR; break; } } else { switch(opera) { case '+': prio = Constant.OPERATORS_PRIO_PLUS_OUT; break; case '-': prio = Constant.OPERATORS_PRIO_SUB_OUT; break; case '*': prio = Constant.OPERATORS_PRIO_MULTY_OUT; break; case '/': prio = Constant.OPERATORS_PRIO_DIV_OUT; break; case '(': prio = Constant.OPERATORS_PRIO_LEFT_BRAK_OUT; break; case ')': prio = Constant.OPERATORS_PRIO_RIGHT_BRAK_OUT; break; default: prio = Constant.OPERATORS_PRIO_ERROR; break; } } return prio; }
3.中綴表示式轉字尾表示式程式碼。
public static void strMidToLast(String strMid,char[] strLast){ char[] stack = new char[strMid.length()];//儲存運算子 int top = 0; int len = strMid.length(); int i = 0;// 計數 int j = 0;// strLast 的下標 int prioIn; int prioOut; while(i != len){ //判斷當前的字元是不是數字。 if(Character.isDigit(strMid.charAt(i))){ strLast[j++] = strMid.charAt(i); i++; }else{//不是數字 if(top == 0){//棧為空。 stack[top++] = strMid.charAt(i); i++; }else{//棧不為空。 prioIn = Get_Prio(stack[top-1],true);//棧內 prioOut = Get_Prio(strMid.charAt(i),false);//棧外 //棧內優先順序高於棧外。數字越小優先順序越高。--->出棧 if(prioIn < prioOut){ strLast[j++] = stack[--top]; //優先順序相等。(遇到括號) }else if(prioIn == prioOut){//括號的情況 top--; i++; }else{ //棧外高於棧內。 ---->入棧 stack[top++] = strMid.charAt(i); i++; } } } } //判斷棧內是否還有運算子 while(top > 0){ strLast[j++] = stack[--top]; } }