java实现字符串四则运算公式解析工具类的方法
作者:零度anngle 发布时间:2021-11-03 09:22:23
标签: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;
}
}
来源:https://blog.csdn.net/zmx729618/article/details/52328377
0
投稿
猜你喜欢
- Spring boot项目结合docker容器用,打了个jar包,启动的时候竟然说:no main manifest attribute,
- 本文实例为大家分享了java实现webservice方式的具体代码,供大家参考,具体内容如下经过测试 jdk1.6.10以下会出现bug 建
- 最近在学习springmvc,今天把springmvc 参数绑定给整理一下,也算个学习笔记吧!@RequestParam 绑定单个请求Req
- 一、广播机制概述通常情况下在学校的每个教室都会装有一个喇叭,这些喇叭是接入到学校广播室的。如果有重要通知,会发送一条广播来告知全校师生。为了
- 最近正式入坑Flutter,首先从环境搭建开始,看了网上好多关于Windows环境搭建的资料,基本都是按官方文档写的,看完的感受是,还不如直
- 前言smart-doc 是一款同时支持 java restful api 和 Apache Dubbo rpc 接口文档生成的工具,smar
- Flink中设计了用户自定义函数体系(User Defined Function,UDF),开发人员实现业务逻辑就是开发UDF。一、环境对象
- 1.定义Token的注解,需要Token校验的接口,方法上加上此注解import java.lang.annotation.ElementT
- 一直使用的是FastJson,感觉还不错,很方便。看了一段别人的分析,觉得很有道理。为什么要使用Fastjson,其实原因不需要太多,喜欢就
- 一、Rxjava使用场景为了模拟实际场景,从wanandroid网站找了二个接口,如下:(对Wanandroid表示感谢!)public i
- 在 fluro 中,定义路由处理器 Handler 时可以指定该页面的默认转场形式,或者在使用 navigateTo 方法是可以设置页面跳转
- 解决Spring in action @valid验证不生效按照书上的示例代码来实现但是,添加了验证但是没有生效。Spring提供了校验Ap
- 1.概述在实际开发过程中,我们经常需要调用对方提供的接口或测试自己写的接口是否合适。很多项目都会封装规定好本身项目的接口规范,所以大多数需要
- @ConfigurationProperties加载外部配置@ConfigurationProperties可以将外部配置文件(比如appl
- 附GitHub源码:WebViewExplore一、WebView的基础配置WebSettings ws = getSettings();w
- 前言在上一篇文章中讲完了SpringMVC的大部分知识,此篇文章中主要讲解 * 。上一篇文章🚩 * 的使用是非常普遍的。例如在 OA系统中通
- java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的。静态方法是属于类的,不是属于类的对象。所以可以直接使用类名加
- 什么是命名查询? Hibernate允许在映射文件中定义字符串形式的查询语句,这种查询方式成为命名查询 使用命名查询有什么好处? 由于使用H
- 概述非对称加密算法与对称加密算法的主要差别在于非对称加密算法用于加密和解密的密钥不相同,非对称加密算法密钥分为公钥和私钥,公钥加密只能用私钥
- 现在就为大家介绍一种基于因子分解的RSA算法,这种加密算法有两种实现形式:1、公钥加密,私钥解密;2、私钥加密,公钥解密。下面就为大家分析一