栈的应用之中缀表达式转后缀表达式

        我们把平时计算的表达式叫做中缀表达式,比如“2+3*5-4*(5-3)”,因为计算符号在数字中间。现在我们需要将中缀表达式转为后缀表达式。

     首先我们需要一个  newstack[ ] 栈  和strLast[ ]  数组。


1,如果遇到数字将数字存入数组strLast中


2,遇到运算符  如果newstack为空就将其存放进去


3,遇到运算符  如果newstack不为空则遵循以下法则

中缀表达式转后缀表达式
 * 规则:
 *      相同等级的运算符,栈内高于栈外
 *          栈外的左括号优先级最高
 *          栈内的左括号优先级最低

 *          栈外的右括号优先级最低

如若栈外高于栈内将其入栈newstack


否则 将栈内元素出栈直到栈内高于栈外或者栈为空



如果相等  ----》遇到()舍弃!!!既可

代码实现

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;

}
public class Test21 {
	//获取优先级的方法
	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;
	}
	//strMid 中缀表达式              strLast 后缀表达式
	public static void strMidTolast(String strMid,char[] strLast){
		int len;
		int i = 0;//遍历中缀表达式
		len = strMid.length();
		char[] newstack = new char[len];//开辟一个新的栈
		int j = 0;//遍历strLast
		int top = 0;//遍历newstack
		int inprio;//栈内元素优先级
		int putprio;//栈外元素优先级
		while(i!=len){//遍历中缀表达式
			if(Character.isDigit(strMid.charAt(i))){//判断是否为数字
				strLast[j++] = strMid.charAt(i);//为数字则放入strLast数组
				i++;//中缀表达式向后移
			}else if(top == 0){//判断newstack[]是否为空
				newstack[top++] = strMid.charAt(i);//为空则入栈
				i++;//中缀表达式向后移
			}else{
				inprio = Get_Prio(newstack[top-1],true);//栈内优先级
				putprio = Get_Prio(strMid.charAt(i),false);//栈外优先级
				if(inprio > putprio){//栈外优先级小于栈内  
					newstack[top++] = strMid.charAt(i);//入栈
					i++;//中缀表达式向后移
				}
				if(inprio == putprio){//等于---->()的情况   舍弃!!!!
					top--;
					i++;//中缀表达式向后移
				}
				if(inprio < putprio){//大于
					strLast[j++] = newstack[--top];//放入strLast数组,继续与栈的下一个进行优先级比较
				}
				
			}
			
		}
		while(top != 0){//将栈里剩余元素出栈并存放于strLast数组中
			strLast[j++] = newstack[--top];
		}
	}
	
	public static void main(String[] args) {
			String  strMid = "2+3*5-4*(5-3)";
			char[] strLast = new char[strMid.length()];
			strMidTolast(strMid,strLast);
			System.out.println(Arrays.toString(strLast));	
	}
}



猜你喜欢

转载自blog.csdn.net/qq_37937537/article/details/80241752