java算术表达式的运算(不使用中缀转后缀)

看网上都是将中缀表达式转为后缀表达式进行运算,很不幸我不会,便自己写了个通俗易懂的方法

核心就是一直使用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;
	}
}

猜你喜欢

转载自blog.csdn.net/zhang3625/article/details/82977017