`

在Java中计算四则运算表达式字符串的值

    博客分类:
  • Java
阅读更多

在项目中有个需求,需要动态的计算一个四则运算表达式的结果,在JS中做这个非常方便,用eval表达式就搞定了,但在Java语言里就没那么容易了,上网搜了一下没有找到满意的,小弟不才,网上很多代码看不明白,唉,无奈下,自己利用Java中的正则表达式做了一个简单的包括了加减乘除及小括号的计算方法。因为时间仓促,为了赶进度,没仔细进行验证,现在贴出来,请大家拍拍砖,有什么好的解决方法,或考虑到效率问题,还请多多指教。

套话少说了,我的程序的思路是:

1、首先循环获取取最小单位的小括号表达式进行加减乘除计算,直到表达式中不包含小括号为止

2、然后对每个不含括号的表达式,在按顺序执行乘除法,直到没有乘除法表达式

3、最后计算所有的加减表达式,执行的顺序就是按顺序执行了

    a)对于负数运算,首先将其负号去除,同时将相应运算单元的加减号转换,然后再进行运算

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 报表工具类
 * @author ZYWANG 2009-7-28
 */
public final class ReportUtil {
	/**
	 * 格式化日期
	 * @param obj 日期对象
	 * @param format 格式化字符串
	 * @return
	 * @author ZYWANG 2009-8-26
	 */
	public static String formatDate(Object obj, String format) {
		if (obj == null)
			return "";

		String s = String.valueOf(obj);
		if (format == null || "".equals(format.trim())) {
			format = "yyyy-MM-dd";
		}
		try {
			SimpleDateFormat dateFormat = new SimpleDateFormat(format);
			s = dateFormat.format(obj);
		} catch (Exception e) {
		}
		return s;
	}

	/**
	 * 格式化数字
	 * @param obj 数字对象
	 * @param format 格式化字符串
	 * @return
	 * @author ZYWANG 2009-8-26
	 */
	public static String formatNumber(Object obj, String format) {
		if (obj == null)
			return "";

		String s = String.valueOf(obj);
		if (format == null || "".equals(format.trim())) {
			format = "#.00";
		}
		try {
			if (obj instanceof Double || obj instanceof Float) {
				if (format.contains("%")) {
					NumberFormat numberFormat = NumberFormat.getPercentInstance();
					s = numberFormat.format(obj);
				} else {
					DecimalFormat decimalFormat = new DecimalFormat(format);
					s = decimalFormat.format(obj);
				}
			} else {
				NumberFormat numberFormat = NumberFormat.getInstance();
				s = numberFormat.format(obj);
			}
		} catch (Exception e) {
		}
		return s;
	}

	/**
	 * 计算字符串四则运算表达式
	 * @param string
	 * @return
	 * @author ZYWANG 2009-8-31
	 */
	public static String computeString(String string) {
		String regexCheck = "[\\(\\)\\d\\+\\-\\*/\\.]*";// 是否是合法的表达式

		if (!Pattern.matches(regexCheck, string))
			return string;

		Matcher matcher = null;
		String temp = "";
		int index = -1;
		String regex = "\\([\\d\\.\\+\\-\\*/]+\\)";// 提取括号表达式
		string = string.replaceAll("\\s", "");// 去除空格
		try {
			Pattern pattern = Pattern.compile(regex);
			// 循环计算所有括号里的表达式
			while (pattern.matcher(string).find()) {
				matcher = pattern.matcher(string);
				while (matcher.find()) {
					temp = matcher.group();
					index = string.indexOf(temp);
					string = string.substring(0, index)
							+ computeStirngNoBracket(temp)
							+ string.substring(index + temp.length());
				}
			}
			// 最后计算总的表达式结果
			string = computeStirngNoBracket(string);
		} catch (NumberFormatException e) {
			return e.getMessage();
		}
		return string;
	}

	/**
	 * 计算不包含括号的表达式
	 * @param string
	 * @return
	 * @author ZYWANG 2009-8-31
	 */
	private static String computeStirngNoBracket(String string) {
		string = string.replaceAll("(^\\()|(\\)$)", "");
		String regexMultiAndDivision = "[\\d\\.]+(\\*|\\/)[\\d\\.]+";
		String regexAdditionAndSubtraction = "(^\\-)?[\\d\\.]+(\\+|\\-)[\\d\\.]+";

		String temp = "";
		int index = -1;

		// 解析乘除法
		Pattern pattern = Pattern.compile(regexMultiAndDivision);
		Matcher matcher = null;
		while (pattern.matcher(string).find()) {
			matcher = pattern.matcher(string);
			if (matcher.find()) {
				temp = matcher.group();
				index = string.indexOf(temp);
				string = string.substring(0, index) + doMultiAndDivision(temp)
						+ string.substring(index + temp.length());
			}
		}

		// 解析加减法
		pattern = Pattern.compile(regexAdditionAndSubtraction);
		while (pattern.matcher(string).find()) {
			matcher = pattern.matcher(string);
			if (matcher.find()) {
				temp = matcher.group();
				index = string.indexOf(temp);
				if (temp.startsWith("-")) {
					string = string.substring(0, index)
							+ doNegativeOperation(temp)
							+ string.substring(index + temp.length());
				} else {
					string = string.substring(0, index)
							+ doAdditionAndSubtraction(temp)
							+ string.substring(index + temp.length());
				}
			}
		}

		return string;
	}

	/**
	 * 执行乘除法
	 * @param string
	 * @return
	 * @author ZYWANG 2009-8-31
	 */
	private static String doMultiAndDivision(String string) {
		String value = "";
		double d1 = 0;
		double d2 = 0;
		String[] temp = null;
		if (string.contains("*")) {
			temp = string.split("\\*");
		} else {
			temp = string.split("/");
		}

		if (temp.length < 2)
			return string;

		d1 = Double.valueOf(temp[0]);
		d2 = Double.valueOf(temp[1]);
		if (string.contains("*")) {
			value = String.valueOf(d1 * d2);
		} else {
			value = String.valueOf(d1 / d2);
		}

		return value;
	}

	/**
	 * 执行加减法
	 * @param string
	 * @return
	 * @author ZYWANG 2009-8-31
	 */
	private static String doAdditionAndSubtraction(String string) {
		double d1 = 0;
		double d2 = 0;
		String[] temp = null;
		String value = "";
		if (string.contains("+")) {
			temp = string.split("\\+");
		} else {
			temp = string.split("\\-");
		}

		if (temp.length < 2)
			return string;

		d1 = Double.valueOf(temp[0]);
		d2 = Double.valueOf(temp[1]);
		if (string.contains("+")) {
			value = String.valueOf(d1 + d2);
		} else {
			value = String.valueOf(d1 - d2);
		}

		return value;
	}

	/**
	 * 执行负数运算
	 * @param string
	 * @return
	 * @author ZYWANG 2010-11-8
	 */
	private static String doNegativeOperation(String string) {
		String temp = string.substring(1);
		if (temp.contains("+")) {
			temp = temp.replace("+", "-");
		} else {
			temp = temp.replace("-", "+");
		}
		temp = doAdditionAndSubtraction(temp);
		if (temp.startsWith("-")) {
			temp = temp.substring(1);
		} else {
			temp = "-" + temp;
		}
		return temp;
	}

	public static void main(String[] args) {
		String s = "1-7+8";
		s = computeString(s);
		System.out.println(s);
	}
}

 特别感谢lping2指出了负数运算的计算BUG。

分享到:
评论
2 楼 zywang 2010-11-08  
lping2 写道
有bug :6-6-6-6-6-6 计算错误

多谢指正,对负数的处理的确有问题!
1 楼 lping2 2010-11-04  
有bug :6-6-6-6-6-6 计算错误

相关推荐

    四则运算表达式计算器

    四则运算表达式计算器可以用多种编程语言实现,如Python、Java、C++、JavaScript等,每种语言都有其特有的数据结构和语法来支持这种计算。 通过以上步骤,我们可以创建一个能够处理任意长度四则运算表达式的计算器...

    四则运算解析器(字符串)

    四则运算解析器是一种计算机程序,它能够接收包含加、减、乘、除等四则运算符的字符串表达式,并将其转化为可执行的计算过程。这个解析器通常用于解决基础的数学问题,对于编程初学者来说,理解并实现这样一个解析器...

    java简易计算器(四则运算、三角函数、实现优先级)

    Java简易计算器是一个基于Java编程语言实现的计算工具,它不仅支持基本的四则运算,还具备处理三角函数的能力,并且已经实现了运算的优先级规则。这个项目的核心是将用户输入的中缀表达式(常见的数学表达式形式)...

    java实现任意四则运算表达式求值算法

    ck.push(token); } else if ("="....总之,这个Java程序提供了一个基础的四则运算表达式求值器,适用于简单的计算任务。对于更复杂的表达式,可能需要引入更高级的解析技术,如编译原理中的词法分析、语法分析等。

    java实现四则运算

    在本主题中,我们将深入探讨如何使用Java实现四则运算,包括中缀表达式到后缀表达式的转换以及利用栈数据结构进行计算。 首先,我们要理解四则运算的基本概念,它们包括加法(+)、减法(-)、乘法(*)和除法(/)...

    表达式求值计算(java实现)

    本篇文章将深入探讨如何使用Java实现一个能够处理四则运算的表达式求值器。 首先,我们需要理解表达式求值的基本概念。表达式通常包含数字、运算符(如加号"+"、减号"-"、乘号"*"、除号"/")以及括号"()",它们通过...

    java 带表达式计算器

    Java 带表达式计算器是一种基于Java编程语言实现的计算器应用,它不仅支持基本的四则运算,还能够处理带有括号的复杂数学表达式。这样的计算器在处理数学问题时,能够解决更复杂的计算需求,比如计算优先级、阶乘、...

    java正则实现解析算术表达式 (仅限+-*/和括号)

    java正则实现解析算术表达式 (仅限+-*/和括号)

    简单的JAVA四则运算

    #### 一、Java四则运算基础 在计算机编程中,四则运算是最基本的数学运算之一,主要包括加法(`+`)、减法(`-`)、乘法(`*`)与除法(`/`)。对于Java这样的面向对象语言而言,实现四则运算不仅涉及到基本的数据类型操作,...

    js库实现中缀表达式(即日常使用的四则运算表达式)转换成后缀表达式(逆波兰式),方便计算机计算

    该库可能提供了一个函数接口,接受一个中缀表达式字符串作为输入,返回对应的后缀表达式字符串。在实际应用中,这个库可以用于动态计算用户输入的表达式,或者在服务器端进行复杂的数据处理。 此外,理解并实现这样...

    java控制台四则运算计算程序源码

    Java控制台四则运算计算程序源码是一种基于Java编程语言实现的简单计算器,它能够处理任意长度的符合四则运算规则的数学表达式。在控制台上进行交互式操作,用户可以输入数学公式,程序会进行解析并计算出结果。这个...

    四则运算的中缀转后缀,逆波兰表达式求值

    `CalculateString.java` 文件很可能是实现中缀转后缀并求值的核心代码,它可能包含了表达式字符串的解析和转换逻辑。在这个文件中,可能会定义一个类,比如 `Calculator`,该类包含一个方法 `infixToPostfix` 来进行...

    IKExpression技术 运算表达式完美解析

    在四则运算表达式方面,IKExpression支持加减乘除等基本运算,同时可以处理括号内的优先级计算,以及负数和浮点数的运算。例如,"2+3*4"这样的表达式可以通过IKExpression轻松解析并得出正确结果。此外,它还允许...

    map中的值替换掉字符串中的变量(含运算)

    ### Map中的值替换掉字符串中的变量(含运算) 在Java编程中,经常遇到需要将预定义的字符串模板中的变量替换为实际值的情况。这在配置文件解析、动态SQL生成等场景中尤为常见。本文将详细介绍如何利用Java标准库...

    删除多余括号 1

    题目要求编写一个程序,去除给定的四则运算表达式中的多余括号,同时保持原表达式的变量和运算符顺序不变,并确保结果与原始表达式等价。这里不涉及正负号的处理,即假设输入的表达式不会包含`(+a)`或`(-a)`的形式。...

    数据结构课程设计表达式求值

    在表达式求值中,可能遇到的错误包括语法错误(如未关闭的括号)、类型错误(如对字符串进行数学运算)以及运算符错误(如除以零)。为避免这些错误,我们需要在解析表达式时进行验证,并在发现问题时提供有意义的...

    表达式求值,加减乘除混合运算

    2. **四则运算**:加、减、乘、除四种基本运算符在栈中进行处理的方式有所不同。乘除的优先级高于加减,因此当遇到乘除操作符时,需要弹出栈顶的两个数进行运算,再将结果入栈;而加减操作符则只影响其后面的一个...

    用Android studio写的一个四则运算计算器源码以及开发说明

    在本项目中,我们探讨的是一个使用Android Studio开发的四则运算计算器应用。这个应用程序专为Android智能手机设计,能够处理包含加法、减法、乘法和除法四种基本运算的数学表达式,并准确地计算出结果。让我们深入...

    表达式计算Java课设报告

    **测试**阶段,需要对各种复杂表达式进行测试,确保程序能够正确解析和计算,包括但不限于基本的四则运算、带有括号的嵌套表达式、以及各种数学函数的组合。 最后,在**总结**中,学生可能讨论了开发过程中的挑战、...

Global site tag (gtag.js) - Google Analytics