java实现字符串四则运算公式解析工具类的方法

项目中用到用户定义运算公式进行就算的需求,这样需要进行字符串四则运算解析,下面提供字符串公式四则运算解析与计算工具类,需要的同学可参考。

工具类如下:FormulaCalculator.java:

package org.nercita.bcp.record.util;

import java.util.ArrayList;
import java.util.LinkedList;

/**
 * @author zhangwenchao
 * @since 2016-08-26
 * 公式计算的工具类
 */
public class FormulaCalculator {

	private static boolean isRightFormat = true;

	public static double getResult(String formula){
		double returnValue = 0;
		try{
			returnValue = doAnalysis(formula);
		}catch(NumberFormatException nfe){
			System.out.println("公式格式有误,请检查:" + formula);
		}catch(Exception e){
			e.printStackTrace();
		}
		if(!isRightFormat){
			System.out.println("公式格式有误,请检查:" + formula);
		}
		return returnValue;
	}

	private static double doAnalysis(String formula){
		double returnValue = 0;
		LinkedList<Integer> stack = new LinkedList<Integer>();
		int curPos = 0;
		String beforePart = "";
		String afterPart = "";
		String calculator = "";
		isRightFormat = true;
		while(isRightFormat&&(formula.indexOf('(') >= 0||formula.indexOf(')') >= 0)){
			curPos = 0;
			for(char s : formula.toCharArray()){
				if(s == '('){
					stack.add(curPos);
				}else if(s == ')'){
					if(stack.size() > 0){
						beforePart = formula.substring(0, stack.getLast());
						afterPart = formula.substring(curPos + 1);
						calculator = formula.substring(stack.getLast() + 1, curPos);
						formula = beforePart + doCalculation(calculator) + afterPart;
						stack.clear();
						break;
					}else{
						System.out.println("有未关闭的右括号!");
						isRightFormat = false;
					}
				}
				curPos++;
			}
			if(stack.size() > 0){
				System.out.println("有未关闭的左括号!");
				break;
			}
		}
		if(isRightFormat){
			returnValue = doCalculation(formula);
		}
		return returnValue;
	}

	private static double doCalculation(String formula) {
		ArrayList<Double> values = new ArrayList<Double>();
		ArrayList<String> operators = new ArrayList<String>();
		int curPos = 0;
		int prePos = 0;
		int minus = 0;
		for (char s : formula.toCharArray()) {
			 if ((s == '+' || s == '-' || s == '*' || s == '/') && minus !=0 && minus !=2) {
				 values.add(Double.parseDouble(formula.substring(prePos, curPos).trim()));
				 operators.add("" + s);
				 prePos = curPos + 1;
				 minus = minus +1;
			 }else{
				 minus =1;
			 }
			 curPos++;
		}
		values.add(Double.parseDouble(formula.substring(prePos).trim()));
		char op;
		for (curPos = 0; curPos <= operators.size() - 1; curPos++) {
			op = operators.get(curPos).charAt(0);
			switch (op) {
			case '*':
				values.add(curPos, values.get(curPos) * values.get(curPos + 1));
				values.remove(curPos + 1);
				values.remove(curPos + 1);
				operators.remove(curPos);
				curPos = -1;
				break;
			case '/':
				values.add(curPos, values.get(curPos) / values.get(curPos + 1));
				values.remove(curPos + 1);
				values.remove(curPos + 1);
				operators.remove(curPos);
				curPos = -1;
				break;
			}
		}
		for (curPos = 0; curPos <= operators.size() - 1; curPos++) {
			op = operators.get(curPos).charAt(0);
			switch (op) {
			case '+':
				values.add(curPos, values.get(curPos) + values.get(curPos + 1));
				values.remove(curPos + 1);
				values.remove(curPos + 1);
				operators.remove(curPos);
				curPos = -1;
				break;
			case '-':
				values.add(curPos, values.get(curPos) - values.get(curPos + 1));
				values.remove(curPos + 1);
				values.remove(curPos + 1);
				operators.remove(curPos);
				curPos = -1;
				break;
			}
		}
		return values.get(0).doubleValue();
	}

	public static void main(String[] args) {
		System.out.println(FormulaCalculator.getResult("3-(4*5)+5"));
		System.out.println(FormulaCalculator.getResult("7/2-(-4)"));
		System.out.println(FormulaCalculator.getResult("1287763200000-1276272000000")/(3600*24*1000));
	}

}

支持四则运算,同时支持负数解析。

另附,小数数据保留位数工具类,SetNumberPrecision.java

package org.nercita.bcp.record.util;

import java.text.DecimalFormat;

/**

 * @author zhangwenchao
 * 小数点 精度的工具类
 */
public class SetNumberPrecision {

	public static String setNumberPrecision(double x,int Number){
		String p="#########0";
		if(Number==0){
			p="#########0";
		}else{
			p="#########0.";
			for(int i=0;i<Number;i++){//for的巧妙运用
				p=p+"0";
			}
		}
		DecimalFormat f = new DecimalFormat(p);
		String s = f.format(x).toString();
		return s;
	}

}

以上这篇java实现字符串四则运算公式解析工具类的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 详解Java中运算符及用法

    在前面的内容已经学会了如何定义变量和初始化变量.定义变量的目的就是为了操作数据.Java 语言中给我们提供了专门用来操作这些数据的代码符号,统称为"运算符". 按照操作符的用法,我们可以分为以下几类: 算术运算符 赋值运算符 自增和自减运算符 逻辑运算符 关系运算符 位运算符 不用担心,它们就是些符号而已,帮我们处理操作数据的.下面用代码实例,一一来说明这些运算符的用法. 1. 算术运算符 算术运算符,就是针对数值变量的加.减.乘.除.取余的算术操作: 加 :+ 减:- 乘:* 除:/

  • Java三目运算中隐藏的自动拆装箱

    最近修改线上bug的时候排查了一个十分隐藏的bug,直接上代码: Integer a = null; boolean flag = true; Integer b = flag ? a : 0; 乍一看是没什么毛病的,但是已运行就会发现报空指针,在idea里面也会警告可能有空指针,这是什么原因呢? 直接看字节码: 0: aconst_null 1: astore_1 2: iconst_1 3: istore_2 4: iload_2 5: ifeq 15 8: aload_1 9: invok

  • Java利用三目运算符比较三个数字的大小

    易于理解版 package com.zhebie.ternary; public class ternary { public static void main(String[] args) { int a = 5, b = 8 , c = 9; a=a>b?a:b; //a与b相比较,将较大值赋值给a a=a>c?a:c; //已经获得较大值得a再与c相比较,将较大值再次赋值给a System.out.println(a); //输出a的值为9 } } 嵌套三目运算版 public clas

  • Java使用BigDecimal进行运算封装的实际案例

    日常对于金额计算,应该都是用的BigDecimal,可是苦于没有好的工具类方法,现在贡献一个我正在用的对于数字计算的工具类,项目中就是用的这个,简单粗暴好用,话不多说,代码奉上(该工具类需要引入google的一个jar,com.google.common.base.Optional,具体maven引入看文章末尾): import java.math.BigDecimal; public class NumberArithmeticUtils { /** * BigDecimal的加法运算封装 *

  • 浅谈Java三目运算

    三目条件运算公式为 x?y:z  其中x的运算结果为boolean类型,先计算x的值,若为true,则整个三目运算的结果为表达式y的值,否则整个运算结果为表达式z的值 例:String s=""; String x="默认值"; s=s.isEmpty()?x:s; 这段代码的意思是:先判断s是否为空(结果是空),然后执行s=x,即执行x 再来一个复杂点的 class Dates { int year,month,day; Dates(int x,int y,int

  • Java 字符串转float运算 float转字符串的方法

    需求:字符串(字符串只有一位小数)转float进行运算, 将结果转成字符串(保留一位小数) 直接上代码: float f1 = 0.1f; String a1 ="1.5"; System.out.println(Float.parseFloat(a1)+f1); 答案:1.6 float f1 = 0.1f; String a1 ="1.6"; System.out.println(Float.parseFloat(a1)+f1); 答案:1.7 说实话,一开始我

  • Java中比较运算符compareTo()、equals()与==的区别及应用总结

    前言 比较运算符用于判断两个数据的大小,例如:大于.等于.不等于.比较的结果是一个布尔值( true 或 false ). Java 中常用的比较运算符如下表所示: 本文主要给大家介绍了关于Java比较运算符compareTo().equals()与==区别及应用的相关内容,下面话不多说了,来一起看看详细的介绍吧 1.== 和 equals的区别: ==主要是两个变量值的比较,返回值为true 或者是false.对于普通变量,如:int a=10; int  b= 10; a==b,返回为 tr

  • java代码执行字符串中的逻辑运算方法

    方式一 public class Test { public static void main(String[] args) throws Exception { String str = "(a or b) and c"; str = str.replaceAll("or", "||"); str = str.replaceAll("and", "&&"); System.out.prin

  • Java编程实现对十六进制字符串异或运算代码示例

    前言:好久没有写博客,最近一年感觉真是好忙,各种做不完的工作.相信很多上班族都会有这种感觉.最近对NFC进行写卡操作,需要计算一个校验位.一般情况下,校验位多数是由前几个字节进行异或运算所得. 现在我就先说一下我使用的场景: 把一个16字节的数据写到CPU卡(如交通卡)里面,最后一字节是校验码---前十五字节异或. 我开始从网上找了一些别人写的算法发现计算后结果不对,或者就是写的太复杂了,于是自己就写了一个,感觉也比较简单,现在分享给大家,希望一起交流一下. 第一节:什么是异或运算(主要摘自百度

  • Java利用移位运算将int型分解成四个byte型的方法

    package 移位运算; public class 移位运算 { public static void main(String[] args) { //00000111 01011011 11001101 00010101 int n=123456789; //n为需要进行移位处理的32位int型初始值 byte[] a =chai(n); for (int i = 0; i < a.length; i++) { byte b=a[i]; System.out.print(b+" &qu

随机推荐