Java用栈实现 中缀表达式转后缀表达式

先了解一下什么是中缀和后缀表达式

中缀表达式就是我们平常写的算式,比如2*(3+4)-8/2,它对应的后缀表达式是234+*82/-。不要着急,接下来我们看看是怎么得到后缀表达式的。

当遇到数字时,直接输出,遇到符号入栈,在入栈之前需要判断各操作符的优先级大小,判断规则如下。

===栈外>栈内: 将栈外操作符入栈

===栈外<栈内: 将栈内操作符出栈

===栈内=栈外: 规定栈内高于栈外,将栈内的出栈

===遇到 ‘(’    :  直接入栈 ,入栈后将其优先级变为最低(即栈外‘(’最高,栈内‘(’最低

           遇到 ‘)’:      出栈所有操作符直达遇到 ‘(’ (栈外右括号优先级最低,低到和栈内左括号优先级相等)

具体执行如下图:(图有些粗糙)


接下来用Java实现一下中缀表达式转后缀表达式


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 TestM1 {
	public static int Get_Prio(char opera,boolean instack)//opera是操作符,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;
	}
	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))){//charAt是Stirng类型里的方法
				strLast[j++] = strMid.charAt(i);//将当前字符写入后缀表达式
				i++;
			}else{
				if(top == 0){//如果栈内没有操作符,让当前操作符入栈
					stack[top++] = strMid.charAt(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);
					}
				}
			}
		}
		//判断栈内是否还有运算符
		while(top > 0){
			strLast[j++] = stack[--top];
		}
	}


猜你喜欢

转载自blog.csdn.net/sinat_37003267/article/details/80242600