看网上都是将中缀表达式转为后缀表达式进行运算,很不幸我不会,便自己写了个通俗易懂的方法
核心就是一直使用split()进行切割表达式字符串,筛选出连乘连除表达式,乘法表达式,除法表达式,减法表达式,加法表达式,将各表达式替换成各表达式计算所得的结果,到最后只需进行加法运算,循环遍历连加即可得出结果
萌新第一篇文章,有错误的地方请大佬指教
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 思路1>替换掉字符串中的特殊字符(*+)
* 2>连乘连除运算->乘法运算->除法运算->乘法运算->减法运算->加法运算
*
* @author 25415
*/
public class test {
public static void main(String[] args) {
double qaq = test.calculatorUtils("1.1+2.2");
BigDecimal qaqa=new BigDecimal(qaq).setScale(2, BigDecimal.ROUND_HALF_UP);//解决浮点数运算产生的精度问题,直接保留小数点后两位四舍五入
System.out.println(qaqa);
}
public static Double calculatorUtils(String total) {
// String total="1+2+3.2*2-4/2.1*2-2/4+4*3.5-9/3";
// 将属于正则表达式中的特殊字符*替换成r,+替换成a,因为后面须将子字符串替换成得出的结果
// 而子字符串包含特殊字符将导致匹配错误
total = total.replaceAll("\\*", "r").replaceAll("\\+", "a");
/**
* 连乘连除运算 计算表达式中包含"r"和"/"的子字符串,将子字符串替换成计算结果
*/
String[] ab = total.split("a|-");
for (String ab2 : ab) {
if (ab2.contains("/") && ab2.contains("r")) {// 筛选出包含"r"和"/"的子字符串
List<String> list2 = new ArrayList<String>();// 将数字数组封装成list集合,便于后面计算后删除操作
String[] a1 = ab2.split("r|/");// 储存数字
for (String bb : a1) {
list2.add(bb);
}
List<String> list = new ArrayList<>();// 储存乘除号
String[] a2 = ab2.split("\\d|\\.");
for (String aa : a2) {
if (!aa.isEmpty()) {
list.add(aa);
}
}
double temp = Double.parseDouble(list2.get(0));// 将数字集合list2中下标为0的元素赋给temp
for (String test : list) {
if ("r".equals(test)) {// 当test为"r"时
temp *= Double.parseDouble(list2.get(1));// 让temp乘于数字集合中下标为1的元素,并将结果赋给temp
list2.remove(1);// 清除已被使用过的下标为1的元素,这样便让下标为2的元素变成下标为1,
}
if ("/".equals(test)) {
temp /= Double.parseDouble(list2.get(1));
list2.remove(1);
}
}
String qwe = String.valueOf(temp);// 将结果转换成String类型
total = total.replaceAll(ab2, qwe);// 将表达式中连乘连除子字符串替换成计算所得出的结果
}
}
/**
* 乘法运算
*/
String[] num1 = total.split("a|-");// 将表达式以a(+)和-作为分隔符进行切割
for (String aa : num1) {
if (aa.contains("r") && !aa.contains("/")) {// 筛选出只包含"r"的子字符串
String[] num2 = aa.split("r");// 将子表达式以"r"作为切割符进行切割
double b = Double.parseDouble(num2[0])
* Double.parseDouble(num2[1]);// 计算结果
String bb = String.valueOf(b); // 将结果转换成String类型,方便下一部替换操作
total = total.replaceAll(aa, bb);
// 将仅包含"*"的子字符串替换成该子字符串计算所得到的结果,这样整个表达式就完成了乘法运算
}
}
/**
* 除法运算 计算表达式中仅包含"/"的子字符串,将子字符串替换成计算结果
*/
String[] num3 = total.split("a|-");// 再次以a(+)和-作为分隔符进行切割
for (String aa2 : num3) {
if (aa2.contains("/") && !aa2.contains("r")) {// 筛选出只包含"/"的子字符串
String[] num4 = aa2.split("/");
double b2 = Double.parseDouble(num4[0])
/ Double.parseDouble(num4[1]);
String bb2 = String.valueOf(b2);
total = total.replaceAll(aa2, bb2);
// 至此整个表达式就完成了除法运算1a2a6.4-4/2.1r2-2.0-0.5a14.0-3.0a3.0
}
}
/**
* 减法运算 至此表达式就变成加减法算术表达式 计算表达式中仅包含减号的子字符串,并将子字符串替换成计算结果
*/
String[] num5 = total.split("a");
for (String aa3 : num5) {
if (aa3.contains("-")) {
String[] num6 = aa3.split("-");
double temp = Double.parseDouble(num6[0]);
for (int i = 1; i < num6.length; i++) {
temp -= Double.parseDouble(num6[i]);
}
String temp2 = String.valueOf(temp);
total = total.replaceAll(aa3, temp2);
}
}
/**
* 加法运算 到此表达式就变成加法表达式,只需以"+"切割表达式,循环遍历数组,将数组元素相加即可
*/
String[] num7 = total.split("a");
double qq = 0;
for (int i = 0; i < num7.length; i++) {
qq += Double.parseDouble(num7[i]);
}
return qq;
}
}