我们平常写的式子是中缀式
将中缀式转为后缀式让计算机计算,就可以解决计算优先级的问题了。
需要注意的地方:
如果字符equ[i]为0-9的数字
注:
out字符串为"";
把他拼接到out字符串后面
再while循环,条件为0-9字符数字或者小数点
通过循环,可以把多位数和小数从字符数组中提取出来,加进字符串out中
这样一个out就是一个小数或者多位数或者个位数,再将out放进集合List中
if (equ[i] >=‘0’ && equ[i] <=‘9’){
out += equ[i];
while (equ[i + 1] >= ‘0’ && equ[i + 1] <= ‘9’|| equ[i + 1] == ‘.’) {
out += equ[i + 1];
i++;
}
list.add(out);
out = “”;
continue;
}
有一个比较严重的问题,数组下标出界
假如传进的式子为“7+8”,当读到8时,此时i+1为3,数组最大长度为3,下标出界,
为避免这样的问题,可以做下面处理1或者处理2
1.方法sweap(String equation){}
传入需计算的中缀式字符串,该方法可以将中缀式转化为后缀式,并且把后缀式的每个数字,加减乘除,小数,以字符串的形式存进List的集合中,最后返回List的集合;
存集合好处,可以存小数,多位数
public static List<String> sweap(String equation) {
Stack<Character> stack = new Stack<>();
//***********************************
//处理1
equation=equation+"?";
//***********************************
char[] equ = equation.toCharArray();
List<String> list = new ArrayList<>();
int len = equ.length;
String out = "";
for (int i = 0; i < len; i++) {
//1.如果字符equ[i]为'(';
if (equ[i] == '(') {
stack.push('(');
continue;
}
//2.如果字符equ[i]为0-9的数字
if (equ[i] >='0' && equ[i] <='9'){
out += equ[i];
//********************************************************************************
// 处理2
// if(i+1<len){
// while (equ[i + 1] >= '0' && equ[i + 1] <= '9'|| equ[i + 1] == '.') {
// System.out.println("i+");
// out += equ[i + 1];
// i++;
// }}
//*********************************************************************************
while (equ[i + 1] >= '0' && equ[i + 1] <= '9'|| equ[i + 1] == '.') {
out += equ[i + 1];
i++;}
list.add(out);
out = "";
continue;
}
//3.如果字符equ[i]为加号或者减号
if (equ[i] == '+' || equ[i] == '-') {
while (!stack.empty() && stack.peek() != '(') {
list.add(stack.pop().toString());
}
stack.push(equ[i]);
continue;
}
//4.如果字符equ[i]为乘号或者除号
if (equ[i] == '*' || equ[i] == '/') {
while (!stack.empty() && (stack.peek() == '*' || stack.peek() == '/')) {
list.add(stack.pop().toString());
}
stack.push(equ[i]);
continue;
}
//5.如果equ[i]为')'
if (equ[i] == ')') {
while (!stack.empty() && stack.peek() != '(') {
list.add(stack.pop().toString());
}
stack.pop();
continue;
}
}
//6.把栈中剩余的字符放进List集合中
while (!stack.empty()) {
list.add(stack.pop().toString());
}
return list;
}
2.方法operation(List list) {}
传入存取后缀式的集合List对象,该方法可以让计算机计算后缀式,最后以float的形式返回结果
public float operation(List<String> list) {
Stack<Float> stack = new Stack<>();
float result = 0;
int len = list.size();
for (int i = 0; i < len; i++) {
String ch = list.get(i);
try {
//如果f转成float出现异常,那么f就不是数字
float f = Float.parseFloat(ch);
stack.push(f);
} catch (Exception e) {
result = count(ch, stack.pop(), stack.pop());
stack.push(result);
}
}
return stack.pop();
}
//eq:运算符,eq1:运算符右边的数字,eq2:运算符左边的数字
public static float count(String eq, float eq1, float eq2) {
if (eq.equals("+")) {
return eq2 + eq1;
}
if (eq.equals("-")) {
return eq2 - eq1;
}
if (eq.equals("*")) {
return eq2 * eq1;
}
if (eq.equals("/")) {
return eq2 * eq1;
}
return 0;
}
main方法示例
public static void main(String[] args) {
//String str = "1.5+5+2*(3*(3-1*2+1))"+"?";
String str="7+8";
DAO dao = new DAO();
System.out.println(dao.operation((DAO.sweap(str))));
}
结果展示