阶梯费用计算(配置化_最小demo)

本文旨在提供一种配置化思路计算阶梯费用,更高级的做法则是通过数据库配置,注册中心等;在表达式上可以采用自定义或者spel表达式等其他方式进行处理;(代码仅展示最小demo,部分不完善orBug地方自行补充)

思路:N个区间对应N个费用模式(费用模式可以根据需要进行扩展);

          先进行第一个区间的值,收集后续区间,然后按照最大区间差值加权

          

目录

一、核心代码

二、工具类DataCompareUtils


一、核心代码

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.List;/*** description:*/
public class FeeT {public static void main(String[] args) {/*** 如果 value落在区间N,*     当前区间则为当前值减去最小值 加权计算*     剩余区间则按照区间最大值  加权计算,**/String expression = "(0,10]#(10,20]#(20,100]#(100,";String model = "*1#*2#*2#+1";String value = "101";BigDecimal bigDecimal = getStepFeeItem(expression, model, value);System.out.println(bigDecimal.doubleValue());}private static BigDecimal getStepFeeItem(String expression, String model, String value) {BigDecimal bigDecimal = new BigDecimal(0);String[] expressionArr = expression.split("#");String[] modelArr = model.split("#");List<String> expressionA = new ArrayList<>();/*** 计算第一个区间的值*/bigDecimal = computeFirst(value, bigDecimal, expressionArr, modelArr, expressionA);bigDecimal = computeLast(bigDecimal, expressionA);return bigDecimal;}private static BigDecimal computeLast(BigDecimal bigDecimal, List<String> expressionA) {for (String s : expressionA) {String[] split = s.split("#");BigDecimal computeValue = computeValue(BigDecimal.valueOf(Double.parseDouble(maxRange(split[1]))).subtract(BigDecimal.valueOf(Double.parseDouble(minRange(split[1])))), split[0]);bigDecimal = bigDecimal.add(computeValue);}return bigDecimal;}private static BigDecimal computeFirst(String value, BigDecimal bigDecimal, String[] expressionArr, String[] modelArr, List<String> expressionA) {for (int i = expressionArr.length - 1; i >= 0; i--) {if (DataCompareUtils.checkValue(value, expressionArr[i])) {BigDecimal computeValue = computeValue(BigDecimal.valueOf(Double.parseDouble(value)).subtract(BigDecimal.valueOf(Double.parseDouble(minRange(expressionArr[i])))), modelArr[i]);bigDecimal = bigDecimal.add(computeValue);//如果目标值在遍历区间,则剩余区间则放到另外一个队列中for (int j = i - 1; j >= 0; j--) {expressionA.add(new StringBuilder().append(modelArr[j]).append("#").append(expressionArr[j]).toString());}break;}}return bigDecimal;}public static String minRange(String expression) {String all = expression.replaceAll("[^0-9.,]", "");String[] split = all.split(",");return split[0];}public static String maxRange(String expression) {String all = expression.replaceAll("[^0-9.,]", "");String[] split = all.split(",");return split[1];}public static BigDecimal computeValue(BigDecimal value, String expression) {String symbol = expression.replaceAll("[^\\+\\-\\*/]", ""); //+-*/String feeValue = expression.replaceAll("[\\+\\-\\*/]", "");// 1switch (symbol) {case "+":return value.add(BigDecimal.valueOf(Double.parseDouble(feeValue))).setScale(4, BigDecimal.ROUND_CEILING);case "-":return value.subtract(BigDecimal.valueOf(Double.parseDouble(feeValue))).setScale(4, BigDecimal.ROUND_CEILING);case "*":return value.multiply(BigDecimal.valueOf(Double.parseDouble(feeValue))).setScale(4, BigDecimal.ROUND_CEILING);case "/":return value.divide(BigDecimal.valueOf(Double.parseDouble(feeValue)), MathContext.DECIMAL64).setScale(4, BigDecimal.ROUND_CEILING);default:return value;}}}

二、工具类DataCompareUtils

数据比较工具,不同区间的值进行比较


import org.apache.commons.lang3.StringUtils;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;/*** description: 数据比较工具类*/
public class DataCompareUtils {private DataCompareUtils() {}public static final Map<String, String> SYMBOL_MAP = new HashMap<>();static {SYMBOL_MAP.put("(,)", "(,)");SYMBOL_MAP.put("[,)", "[,)");SYMBOL_MAP.put("(,]", "(,]");SYMBOL_MAP.put("[,]", "[,]");SYMBOL_MAP.put("[,", "[,");SYMBOL_MAP.put("(,", "(,");SYMBOL_MAP.put(",]", ",]");SYMBOL_MAP.put(",)", ",)");}public static final String SYMBOL_01 = "(,)";public static final String SYMBOL_02 = "[,)";public static final String SYMBOL_03 = "(,]";public static final String SYMBOL_04 = "[,]";public static final String SYMBOL_05 = "[,";public static final String SYMBOL_06 = "(,";public static final String SYMBOL_07 = ",]";public static final String SYMBOL_08 = ",)";private static final Pattern NUMBER_REG = Pattern.compile("^-?\\d+(\\.\\d+)?$");/*** 双边校验 返回true说明不符合* [4,5] (3,5)* 不符合返回false,符合区间返回true** @param value* @return*/public static boolean checkValue(String value, String config) {if (StringUtils.isEmpty(config)) {return false;}config = config.replace(" ", "").replace(",", ",").replace("(", "(").replace("【", "[").replace("】", "]").replace(")", ")").trim();config = config.replaceAll("[^0-9.()\\[\\],]", ""); //获取 [3,8]String s = config.replaceAll("[^\\[\\]\\(\\),]", "");//获取 []if (StringUtils.isEmpty(SYMBOL_MAP.get(s))) {return false;}/*** 第一个为值  第二个为配置表达式*/boolean flag = false;switch (s) {case SYMBOL_01:flag = checkLeftNoAndRightNo(value, config);break;case SYMBOL_02:flag = checkLeftAndRightNo(value, config);break;case SYMBOL_03:flag = checkLeftNoAndRight(value, config);break;case SYMBOL_04:flag = checkLeftAndRight(value, config);break;case SYMBOL_05:flag = checkLeft(value, config);break;case SYMBOL_06:flag = checkLeftNo(value, config);break;case SYMBOL_07:flag = checkRight(value, config);break;case SYMBOL_08:flag = checkRightNo(value, config);break;default:break;}return flag;}//(5,8)public static boolean checkLeftNoAndRightNo(String value, String config) {String range = config.replace("(", "").replace(")", "");String[] split = range.split(",");return checkNoIncludeMin(value, split[0]) && checkNoIncludeMax(value, split[1]);}//(5,8]public static boolean checkLeftNoAndRight(String value, String config) {String range = config.replace("(", "").replace("]", "");String[] split = range.split(",");return checkNoIncludeMin(value, split[0]) && checkIncludeMax(value, split[1]);}//[5,8)public static boolean checkLeftAndRightNo(String value, String config) {String range = config.replace("[", "").replace(")", "");String[] split = range.split(",");return checkIncludeMin(value, split[0]) && checkNoIncludeMax(value, split[1]);}//[5,8]public static boolean checkLeftAndRight(String value, String config) {String range = config.replace("[", "").replace("]", "");String[] split = range.split(",");return checkIncludeMin(value, split[0]) && checkIncludeMax(value, split[1]);}//(5,public static boolean checkLeftNo(String value, String config) {String range = config.replace("(", "").replace(",", "");return checkNoIncludeMin(value, range);}//[5,public static boolean checkLeft(String value, String config) {String range = config.replace("[", "").replace(",", "");return checkIncludeMin(value, range);}//,8)public static boolean checkRightNo(String value, String config) {String range = config.replace(")", "").replace(",", "");return checkNoIncludeMax(value, range);}//,8]public static boolean checkRight(String value, String config) {String range = config.replace("]", "").replace(",", "");return checkIncludeMax(value, range);}/*** 校验下限 不含 (6,** @param value* @param target* @return*/public static boolean checkNoIncludeMin(String value, String target) {if (StringUtils.isEmpty(value) || StringUtils.isEmpty(target)) {return false;}if (BigDecimal.valueOf(Double.parseDouble(value)).compareTo(BigDecimal.valueOf(Double.parseDouble(target))) > 0) {return true;}return false;}/*** 含最小 [6,** @param value* @param target* @return*/public static boolean checkIncludeMin(String value, String target) {if (StringUtils.isEmpty(value) || StringUtils.isEmpty(target)) {return false;}if (BigDecimal.valueOf(Double.parseDouble(value)).compareTo(BigDecimal.valueOf(Double.parseDouble(target))) >= 0) {return true;}return false;}/*** 最大包含  ,6]** @param value* @param target* @return*/public static boolean checkIncludeMax(String value, String target) {if (StringUtils.isEmpty(value) || StringUtils.isEmpty(target)) {return false;}if (BigDecimal.valueOf(Double.parseDouble(value)).compareTo(BigDecimal.valueOf(Double.parseDouble(target))) <= 0) {return true;}return false;}/*** 不含最大校验    ,6)** @param value* @param target* @return*/public static boolean checkNoIncludeMax(String value, String target) {if (StringUtils.isEmpty(value) || StringUtils.isEmpty(target)) {return false;}if (BigDecimal.valueOf(Double.parseDouble(value)).compareTo(BigDecimal.valueOf(Double.parseDouble(target))) < 0) {return true;}return false;}/*** 判断是否为数字** @param value* @return*/public static boolean checkIsNumber(String value) {return NUMBER_REG.matcher(value).matches();}//\u00A0,\u0020,\u3000
//    1.不间断空格\u00A0,主要用在office中,让一个单词在结尾处不会换行显示,快捷键ctrl+shift+space ;
//2.半角空格(英文符号)\u0020,代码中常用的;
//3.全角空格(中文符号)\u3000,中文文章中使用;public static String replaceSpecialEmpty(String value) {if (StringUtils.isEmpty(value)) {return value;}return value.replace("\\u00A0", "").replace("\\u0020", "").replace("\\u3000", "");}public static void main(String[] args) {List<String> arrayList = new ArrayList<>();arrayList.add("(5,8)");arrayList.add("[5,8)");arrayList.add("(5,8]");arrayList.add("[5,8]");arrayList.add("[5,");arrayList.add("(5,");arrayList.add(",8]");arrayList.add(",8)");String target = "8.01";for (String s : arrayList) {boolean checked = checkValue(target, s);System.out.printf("s:%s ,%s, %s", s, target, checked);System.out.println();}}}

三、效果

String expression = "(0,10]#(10,20]#(20,100]#(100,";
String model = "*1#*2#*2#+1";
String value = "101";

1+80*2+10*2+10

1+160+20+10=191

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/87344.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【leetcode】前缀和

内容摘抄自&#xff1a; 小而美的算法技巧&#xff1a;前缀和数组 | labuladong 的算法小抄 一维数组的前缀和 看这个 preSum 数组&#xff0c;若想求索引区间 [1, 4] 内的所有元素之和&#xff0c; 就可以通过 preSum[5] - preSum[1] 得出。 class NumArray {private:// 前缀…

内网隧道—HTTP\DNS\ICMP

本文仅限于安全研究和学习&#xff0c;用户承担因使用此工具而导致的所有法律和相关责任&#xff01; 作者不承担任何法律和相关责任&#xff01; HTTP隧道 Neo-reGeorg Neo-reGeorg 是一个旨在积极重构 reGeorg 的项目&#xff0c;目的是&#xff1a; 提高可用性&#xff0…

【双指针_盛最多水的容器_C++】

题目解析 盛最多水的容器 算法原理 向内枚举&#xff1a; weight一定会减小 height不是不变就是减小要求的是盛水最多的容器&#xff0c;那么这些枚举情况就不需要。 拿比较小的数去向内枚举&#xff0c;v一直在减小&#xff0c;所以说直接排除 编写代码 class Soluti…

智汇云舟入选IDC《中国智慧城市数字孪生技术评估,2023》报告

8月7日&#xff0c;国际数据公司&#xff08;IDC&#xff09;发布了《中国智慧城市数字孪生技术评估&#xff0c;2023》报告。智汇云舟凭借在数字孪生领域的创新技术与产品&#xff0c;入选《2023中国数字孪生城市技术提供商图谱》。 报告通过公开征集的形式进行申报&am…

SpringBoot07——VueX

共享组件之间的数据&#xff0c;集中管理 这一部分某人要打ow我就跳过没看了&#xff0c;哼&#xff0c;都怪某人

C#,数值计算——Dynpro的计算方法与源程序

给定向量nstate&#xff0c;其整数值是每个状态中的状态数阶段&#xff08;第一和最后阶段为1&#xff09;&#xff0c;并给定函数成本&#xff08;j&#xff0c;k&#xff0c;i&#xff09;返回在阶段i的状态j和的状态k之间移动的成本阶段i1&#xff0c;此例程返回与nstate长度…

vue全局组件自动注册直接使用,无需单独先引用注册再使用

目录结构&#xff1a; 本案例是在根目录下components文件夹测试的&#xff0c;文件位置项目内任意&#xff0c;确保在main.js挂载路径正确即可 1、新建文件夹&#xff08;名字随意&#xff09;zxy_components (放自己组件的地方) 2、在zxy_components文件夹下 &#xff01;新建…

TSINGSEE青犀视频安防监控视频平台EasyCVR设备在线,视频无法播放的原因排查

可支持国标GB28181、RTMP、RTSP/Onvif、海康Ehome、海康SDK、大华SDK、宇视SDK等多种协议接入的安防监控视频平台EasyCVR基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;可在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、…

[考研机试] KY20 完数VS盈数 清华大学复试上机题 C++实现

描述 一个数如果恰好等于它的各因子(该数本身除外)子和&#xff0c;如&#xff1a;6321。则称其为“完数”&#xff1b;若因子之和大于该数&#xff0c;则称其为“盈数”。 求出2到60之间所有“完数”和“盈数”。 输入描述&#xff1a; 题目没有任何输入。 输出描述&#…

PyTorch 微调终极指南:第 1 部分 — 预训练模型及其配置

一、说明 如今&#xff0c;在训练深度学习模型时&#xff0c;通过在自己的数据上微调预训练模型来迁移学习已成为首选方法。通过微调这些模型&#xff0c;我们可以利用他们的专业知识并使其适应我们的特定任务&#xff0c;从而节省宝贵的时间和计算资源。本文分为四个部分&…

【electron】electron项目创建的方式:

文章目录 【1】npm init quick-start/electron&#xff08;推荐&#xff09;【2】 克隆仓库&#xff0c;快速启动【3】 通过脚手架搭建项目【4】 手动创建项目 【Electron官网】https://www.electronjs.org/zh/docs/latest/api/app 【1】npm init quick-start/electron&#xf…

spring的aop动态代理对象注入时机

bean生命周期&#xff1a; bean实例化populateBean填充属性invokeAwareMethods调用aware方法postProcessBeforeInitialization后置处理器before方法initializeBean初始化beanpostProcessAfterAfterInitialization后置处理器after方法 代理对象注入有两种情况&#xff1a;提前和…

什么是CSS Grid布局?什么是Flexbox布局?它们两者有什么不同?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CSS Grid布局⭐ Flexbox布局⭐ 不同之处⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web…

基于MSP430 红外避障-遥控小车(电赛必备 附项目代码)

文章目录 一、硬件清单二、模块连接三、程序设计四、项目源码 项目环境&#xff1a; 1. MSP430F55292. Code Composer Studio3. 蓝牙调试助手 项目简介&#xff1a; 小车可分为3种工作模式&#xff0c;每种工作模式都会打印在OLED显示屏上&#xff0c;通过按键转换工作模式。 模…

SQL | 过滤数据

4-过滤数据 4.1-使用WHERE子句 数据根据 WHERE 子句中指定的搜索条件进行过滤。WHERE 子句在表名&#xff08; FROM 子句&#xff09;之后给出。 select prod_name,prod_price from products where prod_price 3.49; 上述语句查询价格为3.49的行&#xff0c;然后输出名字和…

用chatGPT从左右眼图片生成点云数据

左右眼图片 需求 需要将左右眼图像利用视差生成三维点云数据 先问问chatGPT相关知识 进一步问有没有现成的软件 chatGPT提到了OpenCV&#xff0c;我们让chatGPT用OpenCV写一个程序来做这个事情 当然&#xff0c;代码里面会有一些错误&#xff0c;chatGPT写的代码并不会做模…

华为网络篇 RIPv2的基础配置-25

难度 1复杂度1 目录 一、实验原理 1.1 RIP的版本 1.2 RIP的路由更新方式 1.3 RIP的计时器 1.4 RIP的防环机制 二、实验拓扑 三、实验步骤 四、实验过程 总结 一、实验原理 RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;&am…

日撸java_day61-62

决策树 package machineLearning.decisiontree;import weka.core.Instance; import weka.core.Instances;import java.io.FileReader; import java.util.Arrays;/*** ClassName: ID3* Package: machineLearning.decisiontree* Description: The ID3 decision tree inductive …

css flex 上下结构布局

display: flex; flex-flow: column; justify-content: space-between;

(原创)Flutter与Native页面互相跳转

前言 实际开发混合项目时&#xff0c;常常会有页面跳转的需求 如果是原生界面和flutter界面需要互相跳转 这种情况应该怎么处理呢&#xff1f; 今天这篇博客主要就来介绍下这个情况 其实想一下&#xff0c;这个问题可以拆成四个小的问题来分析&#xff1a; 1&#xff1a;原生界…