【纯java代码实现字符串运算符或公式计算,支持函数,不借助第三方依赖、工具】
2024-01-03 09:19:31
效果图
代码
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author zwb
* @version 1.0
* @Date 2024/1/2
* @Description: 字符串公式计算
* @Description: 支持运算符:加减乘除,等于,不等于,大于,小于,大于等于,小于等于
* @Description: 支持函数:IF(,,),SUM(),AVG(),ABS(),MAX(),MIN()
*/
public class StrFormulaUtil {
public static void main(String[] args) {
String str = "";
//加减乘除
str = "1*(5-3)/2";
System.out.println(str+"的运算结果为:"+initResult(str));
//IF(条件,真值,假值)条件函数
str = "20-IF(1>=2,5,6)";
System.out.println(str+"的运算结果为:"+initResult(str));
//SUM(值,值,值)求和函数
str = "20-SUM(1,2,3,4,5)";
System.out.println(str+"的运算结果为:"+initResult(str));
//AVG(值,值,值)平均值函数
str = "20-AVG(2,4,8,2)";
System.out.println(str+"的运算结果为:"+initResult(str));
//MAX(值,值,值)最大值函数
str = "20-MAX(1,2,3,4,5)";
System.out.println(str+"的运算结果为:"+initResult(str));
//MIN(值,值,值)最小值函数
str = "20-MIN(1,2,3,4,5)";
System.out.println(str+"的运算结果为:"+initResult(str));
}
/**
* @author zwb
* @param info
* @Description: 公式计算获取结果
*/
public static String initResult(String info){
return initBracket("("+info+")");
}
/**
* @author zwb
* @param str
* @Description: 核心计算模块
*/
public static String initNum(String str){
String symbol[] = {"+","-","*","/",">","<","=","!=",">=","<="};
int add = str.indexOf("+");
int subtract = str.indexOf("-");
if (subtract!=-1){
String num="";
if (subtract-1>=0){
num = str.substring(subtract-1, subtract);
try {
Integer.parseInt(num);
} catch(NumberFormatException e) {
subtract=-1;
}
}else {
subtract=-1;
}
}
int multiply = str.indexOf("*");
int divide = str.indexOf("/");
int dy = str.indexOf(">");
int xy = str.indexOf("<");
int dd = str.indexOf("=");
int bdd = str.indexOf("!=");
int dyd = str.indexOf(">=");
int xyd = str.indexOf("<=");
int i=0;
int j=0;
if (multiply==-1&÷==-1&&add==-1&&subtract==-1&&dy==-1&&xy==-1&&dd==-1&&dyd==-1&&xyd==-1){
return str;
}
if (multiply!=-1||divide!=-1){
j=1;
i=(multiply==-1)?divide:((divide==-1)?multiply:(multiply<divide?multiply:divide));
}else if (add!=-1||subtract!=-1){
j=1;
i=(add==-1)?subtract:((subtract==-1)?add:(add<subtract?add:subtract));
}else if (bdd!=-1||dyd!=-1||xyd!=-1){
j=2;
Integer index[] = {bdd,dyd,xyd};
List<Integer> indexList = Arrays.asList(index).stream().filter(x->x!=-1).collect(Collectors.toList());
i= Collections.min(indexList);
}else if (dy!=-1||xy!=-1||dd!=-1){
j=1;
Integer index[] = {dy,xy,dd};
List<Integer> indexList = Arrays.asList(index).stream().filter(x->x!=-1).collect(Collectors.toList());
i=Collections.min(indexList);
}
String strs = "";
if (Arrays.asList(symbol).contains(str.substring(i,i+j))){
String regex = "[\\+\\-\\*/><=(!=)(>=)(<=)]";
String left = str.substring(0, i);
String right = str.substring(i+j, str.length());
String[] lefts = left.split(regex);
String[] rights = right.split(regex);
if ("-".equals(right.charAt(0)+"")){
rights=right.substring(1).split(regex);
rights[0] = "-"+rights[0];
}
String leftStr = left.substring(0,left.length()-lefts[lefts.length - 1].length());
String rightStr = right.substring(rights[0].length(),right.length());
if ("*".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+leftNum.multiply(rightNum)+rightStr;
}else if ("/".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+leftNum.divide(rightNum,4,BigDecimal.ROUND_HALF_UP)+rightStr;
}else if ("+".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+leftNum.add(rightNum)+rightStr;
}else if ("-".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+leftNum.subtract(rightNum)+rightStr;
}else if ("!=".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+(leftNum.compareTo(rightNum)!=0)+rightStr;
}else if (">=".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+(leftNum.compareTo(rightNum)>=0)+rightStr;
}else if ("<=".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+(leftNum.compareTo(rightNum)<=0)+rightStr;
}else if (">".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+(leftNum.compareTo(rightNum)>0)+rightStr;
}else if ("<".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+(leftNum.compareTo(rightNum)<0)+rightStr;
}else if ("=".equals(str.substring(i,i+j))){
BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
BigDecimal rightNum = new BigDecimal(rights[0]);
strs = leftStr+(leftNum.compareTo(rightNum)==0)+rightStr;
}else {
strs = left+str.substring(i,i+j)+right;
}
}
boolean flag = false;
for (String item : Arrays.asList(symbol)) {
if (strs.contains(item)){
flag = true;
}
}
if (flag){
strs = initNum(strs);
}
return strs;
}
/**
* @author zwb
* @param info,select
* @Description: 指定字符出现的下标抓取
*/
public static List<Integer> getStrToIndexOf(String info,String select){
//记录出现的位置
List<Integer> countList = new ArrayList<>();
if (info==null){
return countList;
}
//从最前方开始检索
int start = 0;
//获取检索字符长度
int index = select.length();
while (true) {
if (info.indexOf(select, start) != -1) {
//找到对应字符所在索引,当找到后,将下次寻找的位置转换到当前已找到的位置
start = info.indexOf(select, start);
countList.add(start);
//改变下次检索位置 如:yelloye 从索引0开始查找ye,找到后start = 0;则下次从索引2开始检索(即l处)
start += index; //涉及到多个字符时比 start++检索速度快
} else {
break;
}
}
return countList;
}
/**
* @author zwb
* @param body
* @Description: 公式核心拆解方法
*/
public static String initBracket(String body){
List<Integer> startList = getStrToIndexOf(body, "(");
List<Integer> endList = getStrToIndexOf(body, ")");
Integer end = endList.get(0);
Integer start = Collections.max(startList.stream().filter(s -> s < end).collect(Collectors.toList()));
String left = body.substring(0,start);
String right = body.substring(end+1,body.length());
String middle = body.substring(start+1,end);
if (left.length()>=2&&"IF".equals(left.substring(left.length()-2,left.length()))){//IF函数
middle = initIf(middle);
left = left.substring(0,left.length()-2);
}else if (left.length()>=3&&"SUM".equals(left.substring(left.length()-3,left.length()))){//SUM函数
middle = initSUM(middle);
left = left.substring(0,left.length()-3);
}else if (left.length()>=3&&"AVG".equals(left.substring(left.length()-3,left.length()))){//AVG函数
middle = initAVG(middle);
left = left.substring(0,left.length()-3);
}else if (left.length()>=3&&"ABS".equals(left.substring(left.length()-3,left.length()))){//ABS函数
middle = initABS(middle);
left = left.substring(0,left.length()-3);
}else if (left.length()>=3&&"MAX".equals(left.substring(left.length()-3,left.length()))){//MAX函数
middle = initMAX(middle);
left = left.substring(0,left.length()-3);
}else if (left.length()>=3&&"MIN".equals(left.substring(left.length()-3,left.length()))){//MIN函数
middle = initMIN(middle);
left = left.substring(0,left.length()-3);
}else {
middle = initNum(middle);
}
String content = left+middle+right;
if (content.indexOf("(")!=-1||content.indexOf(")")!=-1){
content = initBracket(content);
}
return content;
}
/**
* @author zwb
* @param str
* @Description: IF(条件,真值,假值)函数计算
* @Description: 判断条件是否成立,成立则取第一个值,不成立则取第二个值
*/
public static String initIf(String str){
String[] split = str.split(",");
String condition = initNum(split[0]);
String trueValue = initNum(split[1]);
String falseValue = initNum(split[2]);
if ("true".equals(condition)){
return trueValue;
}
if ("false".equals(condition)){
return falseValue;
}
if (Integer.valueOf(condition)>0){
return trueValue;
}else {
return falseValue;
}
}
/**
* @author zwb
* @param str
* @Description: SUM(值,值,值)函数计算
* @Description: 求所有值的和
*/
public static String initSUM(String str){
String[] split = str.split(",");
BigDecimal sumAmount = new BigDecimal(0);
for (String s : split) {
sumAmount=sumAmount.add(new BigDecimal(initNum(s)));
}
return sumAmount.toString();
}
/**
* @author zwb
* @param str
* @Description: ABG(值,值,值)函数计算
* @Description: 求所有值的平均值
*/
public static String initAVG(String str){
String[] split = str.split(",");
BigDecimal sumAmount = new BigDecimal(0);
for (String s : split) {
sumAmount=sumAmount.add(new BigDecimal(initNum(s)));
}
return sumAmount.divide(new BigDecimal(split.length),4,BigDecimal.ROUND_HALF_UP).toString();
}
/**
* @author zwb
* @param str
* @Description: ABG(值)函数计算
* @Description: 求数字的绝对值
*/
public static String initABS(String str){
double abs = Math.abs(Double.valueOf(initNum(str)));
return abs+"";
}
/**
* @author zwb
* @param str
* @Description: MAX(值,值,值)函数计算
* @Description: 求出最大值
*/
public static String initMAX(String str){
String[] split = str.split(",");
BigDecimal maxAmount = new BigDecimal(0);
for (String s : split) {
if (new BigDecimal(initNum(s)).compareTo(maxAmount)>0){
maxAmount = new BigDecimal(initNum(s));
}
}
return maxAmount.toString();
}
/**
* @author zwb
* @param str
* @Description: MIN(值,值,值)函数计算
* @Description: 求出最小值
*/
public static String initMIN(String str){
String[] split = str.split(",");
BigDecimal minAmount = new BigDecimal(initNum(split[0]));
for (String s : split) {
if (new BigDecimal(initNum(s)).compareTo(minAmount)<0){
minAmount = new BigDecimal(initNum(s));
}
}
return minAmount.toString();
}
}
文章来源:https://blog.csdn.net/qq_47588845/article/details/135338919
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!