一、需要自定义的优先级
package com_1.constant;
//运算符自定义的优先级
public class Constant {
public static final int PRI_ERROR = -1;
//栈外左括号
public static final int PRI_LEFT_OUT = 1;
//栈内乘
public static final int PRI_MULTY_IN = 2;
//栈内除
public static final int PRI_DIV_IN = 2;
//栈外乘
public static final int PRI_MULTY_OUT = 3;
//栈外除
public static final int PRI_DIV_OUT = 3;
//栈内加
public static final int PRI_PLUS_IN = 4;
//栈内减
public static final int PRI_SUB_IN = 4;
//栈外加
public static final int PRI_PLUS_OUT = 5;
//栈外减
public static final int PRI_SUB_OUT = 5;
//栈内左括号
public static final int PRI_LEFT_IN = 10;
//栈外右括号
public static final int PRI_RIGHT_OUT = 10;
}
//得到当前运算符的优先级
public int getPri(char oper,boolean inStack){
int pri = Constant.PRI_ERROR;
//在栈内
if(inStack){
switch (oper){
case '+':
pri = Constant.PRI_PLUS_IN;
break;
case '-':
pri = Constant.PRI_SUB_IN;
break;
case '*':
pri = Constant.PRI_MULTY_IN;
break;
case '/':
pri = Constant.PRI_DIV_IN;
break;
case '(':
pri = Constant.PRI_LEFT_IN;
break;
default:
pri = Constant.PRI_ERROR;
break;
}
}
//栈外
else{
switch (oper){
case '+':
pri = Constant.PRI_PLUS_OUT;
break;
case '-':
pri = Constant.PRI_SUB_OUT;
break;
case '*':
pri = Constant.PRI_MULTY_OUT;
break;
case '/':
pri = Constant.PRI_DIV_OUT;
break;
case '(':
pri = Constant.PRI_LEFT_OUT;
break;
case ')':
pri = Constant.PRI_RIGHT_OUT;
break;
default:
pri = Constant.PRI_ERROR;
break;
}
}
return pri;
}
二、中缀表达式到后缀表达式的转化
*判断数字字符
Character.isDigit(strMid.charAt(i))
//中缀表达式转为后缀表达式
public void strMidToLast(String strMid,char[] strLast){
//栈
char[] stack = new char[strMid.length()];//栈的大小
int top = 0;//栈顶指针
//strMid下标
int i = 0;
//strLast下标
int j = 0;
//当前栈内运算符的优先级
int pri_in = Constant.PRI_ERROR;
//当前栈外运算符的优先级
int pri_out = Constant.PRI_ERROR;
//遍历中缀表达式
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{
//栈内
pri_in = getPri(stack[top - 1],true);
//栈外
pri_out = getPri(strMid.charAt(i),false);
//栈外优先级高——入栈
if(pri_out < pri_in){
stack[top ++] = strMid.charAt(i);
i ++;
}
//栈内优先级高——出栈,并存入后缀表达式
else if(pri_in < pri_out){
strLast[j ++] = stack[top - 1];
top --;
}
//优先级相等——括号匹配,出栈不存入,i往后走
else{
top --;
i ++;
}
}
}
}
//遍历结束,跳出循环,如果栈不为空,将运算符依次出栈并存入后缀表达式
while(top != 0){
strLast[j ++] = stack[-- top];
}
}
三、根据后缀表达式进行计算
//两个数字运算
public int getResult(int a,int b,char oper){
int result = 0;
switch (oper){
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
return -1;
}
/*
根据后缀表达式计算结果
遍历后缀表达式
将数字入栈。碰到运算符,出栈两次,进行运算,并将运算结果再入栈
*/
public int arithmetic(char[] strLast){
//栈
int[] stack = new int[strLast.length];
int top = 0;
//后缀表达式下标
int i = 0;
//两个操作数
int num1 = 0;
int num2 = 0;
//运算结果
int result = 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 oper = strLast[i];
//进行运算
result = getResult(num2,num1,oper);
//结果再次入栈
stack[top ++] = result;
}
i ++;
}
return result;
}