14 . 用栈实现中缀表达式转后缀表达式

转换规则:

  • 相同等级的运算符,栈外高于栈内。
  • 栈外的左括号优先级最高。
  • 栈内的左括号优先级最低。
  • 栈外的右括号优先级最低。低到和栈内的左括号优先级一样。

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

猜你喜欢

转载自blog.csdn.net/alyson_jm/article/details/80240940