中缀表达式变为后缀表达式 如图所示~~
那么用栈怎么来表示呢???
看图啦!!!
第一步:遇到数字直接放到后缀表达式
第二步:优先级高的入栈
第三步:每次入栈之前和栈顶运算符进行优先级比较,如果栈内高于栈外,那么出栈一次
第四步:如果是相同优先级的两个运算符,规定栈内高于栈外
第五步:栈外的左括号优先级最高。入栈之后,优先级变为最低
第六步:栈外的右括号,优先级最低,低到和栈内左括号一样
注意哦~~后缀表达式没有括号的啦
先定义运算符常量
package constant;
/**
* Description:运算符常量
* author:SS
* Date: 2018/12/4 19:01
* packageName: constant
*/
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;
}
功能代码
package dao;
import constant.Constant;
/**
* Description:
* author:SS
* Date: 2018/12/5 14:52
* packageName: dao
*/
public class TestDemoML {
/**
* 得到当前运算符的优先级
* @param opera
* @param instack
* @return
*/
public int getPrio(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;
}
//将中缀表达式转换为后缀表达式的过程
public void strMidToLast(String strMid,char[] strLast){
char[] stack = new char[strMid.length()]; //存放运算符
int top = 0; //栈的下标
int i = 0; //中缀表达式的下标
int j = 0; //后缀表达式的下标
int prio_in = -1; //当前栈内的运算符的优先级
int prio_out = -1;//当前栈外的运算符的优先级
while (i != strMid.length()){
if (Character.isDigit(strMid.charAt(i))){ //判断是否为数字字符
strLast[j] = strMid.charAt(i); //是数字的话直接放进后缀表达式
i++;
j++;
}else { //当为运算符时
if (top == 0){ //栈为空的时候
stack[top++] = strMid.charAt(i); //直接将运算符入栈
i++;
}else { //栈里有运算符时
prio_in = getPrio(stack[top-1],true); //获取栈内的栈顶运算符
prio_out = getPrio(strMid.charAt(i),false); //获取栈外的运算符
if (prio_out < prio_in){ //如果栈外的优先级高于栈内的
stack[top++] = strMid.charAt(i); //入栈
i++;
}else if (prio_out == prio_in){
top--;
i++;
}else { //栈内优先级高于栈外
strLast[j++] = stack[top-1]; //出栈
top--;
}
}
}
}
while (top > 0){
strLast[j++] = stack[--top];
}
}
//计算后缀表达式的结果
/**
*取栈顶运算符和栈顶两个数字进行计算
*计算的结果再入栈,然后再计算
* @param strLast
* @return
*/
public int arithmetic(char[] strLast){
int[] stack = new int[strLast.length];
int top = 0;
int i = 0; //strLast的下标
int result = 0; //存放运算的结果
int num1 = 0;
int num2 = 0;
while (i != strLast.length){
if (Character.isDigit(strLast[i])){ //是数字时
//将数字字符转换为int
String str1 = Character.toString(strLast[i]);
stack[top++] = Integer.parseInt(str1);
}else if (strLast[i] == ' '|| strLast[i] == '\u0000'){ //为空字符或默认值时
}else { //是运算符时
num1 = stack[--top]; //右操作数
num2 = stack[--top]; //左操作数
char opera = strLast[i];
result = getResult(opera,num2,num1);
stack[top++] = result;
}
i++;
}
return result;
}
public int getResult(char opera,int left,int right) {
switch (opera) {
case '+':
return left + right;
case '-':
return left - right;
case '*':
return left * right;
case '/':
return left / right;
}
return -1;
}
}
测试代码
package main;
import dao.TestDemoML;
import java.util.Arrays;
/**
* Description:
* author:SS
* Date: 2018/12/4 19:23
* packageName: main
*/
public class Test {
public static void main(String[] args) {
TestDemoML testDemoML = new TestDemoML();
String strMid = "2+3*5-4*(5-3)";
char[] strLast = new char[strMid.length()];
testDemoML.strMidToLast(strMid,strLast);
System.out.println(Arrays.toString(strLast));
int result = testDemoML.arithmetic(strLast);
System.out.println(result);
}
}