1. 程式人生 > >用棧實現中綴表示式轉字尾表示式

用棧實現中綴表示式轉字尾表示式

轉換規則:

  • 相同等級的運算子,棧外高於棧內。
  • 棧外的左括號優先順序最高。
  • 棧內的左括號優先順序最低。
  • 棧外的右括號優先順序最低。低到和棧內的左括號優先順序一樣。

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];
		}
	}