我们把平时计算的表达式叫做中缀表达式,比如“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));
}
}