学习算法,不许喷哦,学习奋斗中,程序猿之积木堆积者
需求:在B2C中,B端为了考核C端,出现需要根据阶梯达标量来判断该C端是否符合标准,符合标准则根据标准情况奖励产品
例如:小明是供货商、小爱和小霞是经销商,小明需要根据销售数量来判断小爱是不是每天都达标。
小明制定得标准是:
1、合同量小于1吨得时候,每天的总库存量不能低于10件、每天线上库存量不能低于4件,每天的销售量不能低于2件
2、合同量大于1吨且小于4吨得时候,每天的总库存量不能低于50件、每天线上库存量不能低于20件,每天的销售量不能低于12件
....依次类推
100、合同量大于100吨的时候,每天的总库存量不能低于500件、每天线上库存量不能低于300件,每天的销售量不能低于130件
小爱的合同量为:3吨
小霞的合同量为:40吨
如此会得出结论:
合同量范围 | 总库存 | 线上库存 | 销售量 |
0~1 | 10 | 4 | 2 |
1~4 | 50 | 20 | 12 |
100~无穷大 | 500 | 300 | 130 |
为了尽快定位根据合同量下的数据,因此采用以下算法实现
直接上代码
1、引入jar包如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.core</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>test</description>
<properties>
<java.version>1.8</java.version>
<fastjson2.version>2.0.11</fastjson2.version>
</properties>
<dependencies>
<!-- springboot基础应用包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 启动容器undertow -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!-- 阿里数据json处理 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、代码如下:
import com.alibaba.fastjson2.JSON;
import lombok.SneakyThrows;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.*;
import java.util.stream.Collectors;
/**
* 算法理解一课
* 深度理解冒泡和二分法
* @Author: java-cj
* */
@SpringBootTest
@Slf4j
public class TestApi {
/**
* 需求说明
* 根据数据库存储和同量判断当前总库存量是否合格,不合格进行预警或者报警
* 1、合同量是数据库存储的(每年都会有变动,变动意味着营销会变动)
* 2、合同量的区间和区间值是根据客户提供标准(每年都会有调整,因此采用存储可变模式===系统字典存储)
* */
@Test
public void test() {
// 1865
Map<String, Object> map = new HashMap<>();
// 总库存量
map.put("allQty", "{\"region\":\"0\",\"result\":\"1\",\"isAdoptedContract\":\"false\",\"color\":\"#153153\",\"bgColor\":\"#ffffff\",\"defaultColor\":\"#000000\",\"defaultBgColor\":\"#ffffff\"}");
// 线上库存量
//map.put("onlineQty", "{\"region\":\"0,10\",\"result\":\"12,20\","isAdoptedContract":"false",\"color\":\"#153153\",\"bgColor\":\"#ffffff\","defaultColor":"#000000","defaultBgColor":"#ffffff"}");
// 销售量
//map.put("salesQty", "{\"region\":\"0,5,10,15,20\",\"result\":\"2,4,6,8,10\","isAdoptedContract":"false",\"color\":\"#153153\",\"bgColor\":\"#ffffff\","defaultColor":"#000000","defaultBgColor":"#ffffff"}");
JSONObject jsonObject = changeObject("allQty", 0, 10, map);
System.out.println(jsonObject);
}
/**
* 根据数据进行尽快定位数据所在区间
*
* @param key 传入的key(数据库查询出来得字段)
* @param value 传入的value(数据库查询出来得值,目前得总库存量)
* @param contractNum 传入的合同量(数据库中根据数据分析出来得合同量)
*/
@SneakyThrows
public JSONObject changeObject(String key, int value, int contractNum, Map<String, Object> map) {
// 获取字典得值 不行就用map循环
JSONObject object = JSON.parseObject(new JSONObject(map).getString(key));
// 获取结果(数据必须时有序,且必须是一个区间包含一个值)
// 区间结果
String region = object.getString("region");
// 区间对应值结果
String result = object.getString("result");
// 渲染数据颜色
String color = object.getString("color");
// 渲染数据背景颜色
String bgColor = object.getString("bgColor");
// 默认字体颜色
String defaultColor = object.getString("defaultColor");
// 背景颜色
String defaultBgColor = object.getString("defaultBgColor");
// 是否采用合同
boolean isAdoptedContract = object.getBoolean("isAdoptedContract");
JSONObject jsonObject = new JSONObject();
if (contractNum == 0) {
if (value > 0) {
jsonObject.put("value", value);
jsonObject.put("color", defaultColor);
jsonObject.put("bgColor", defaultBgColor);
} else {
jsonObject.put("value", value);
jsonObject.put("color", color);
jsonObject.put("bgColor", bgColor);
}
} else {
// 冒泡法
// int resNum = bubbling(region, result, isAdoptedContract?contractNum:0);
// 二分法
int resNum = dichotomy(region, result, isAdoptedContract?contractNum:0);
if (resNum <= value) {
jsonObject.put("value", value);
jsonObject.put("color", defaultColor);
jsonObject.put("bgColor", defaultBgColor);
} else {
jsonObject.put("value", value);
jsonObject.put("color", color);
jsonObject.put("bgColor", bgColor);
}
}
return jsonObject;
}
/**
* 冒泡获取结果 (效率不高 很慢 完全可以实现)
* @param regin 取值区间
* @param result 区间对应结果
* @param contract 当前拥有合同量
*/
public int bubbling(String regin, String result, int contract) {
List<String> regins = Arrays.asList(regin.split(","));
List<Integer> reginList = regins.stream().map(Integer::parseInt).collect(Collectors.toList());
// 结果
List<String> results = Arrays.asList(result.split(","));
List<Integer> resultList = results.stream().map(Integer::parseInt).collect(Collectors.toList());
// 若入参比数组中最大数还大,则取值最大区间
if (contract >= reginList.get(resultList.size() - 1)) {
return resultList.get(resultList.size() - 1);
}
int iNum = -1;
for (int i = 0; i < reginList.size(); i++) {
if (reginList.get(i) >= contract) {
iNum = i;
break;
}
}
return resultList.get(iNum - 1);
}
/**
* 二分法获取结果
* @param regin 取值区间
* @param result 区间对应结果
* @param contract 当前拥有合同量
*/
public int dichotomy(String regin, String result, int contract) {
// 获取区域
List<String> regins = Arrays.asList(regin.split(","));
List<Integer> reginList = regins.stream().map(Integer::parseInt).collect(Collectors.toList());
// 返回区域结果
List<String> results = Arrays.asList(result.split(","));
List<Integer> resultList = results.stream().map(Integer::parseInt).collect(Collectors.toList());
// 若入参比数组中最大数还大,则取值最大区间
if (contract > reginList.get(resultList.size() - 1)) {
return resultList.get(resultList.size() - 1);
}
// 进行二分
int left = 0;
int right = reginList.size() - 1;
int mid = (left + right) / 2;
int index = -1;
// 查找
while (left <= right) {
if (reginList.get(mid) == contract) {
index = mid;
break;
} else if (reginList.get(mid) < contract) {
left = mid + 1;
} else {
right = mid - 1;
}
mid = (right + left) / 2;
}
if (index == mid) {
return resultList.get(index);
} else {
return resultList.get(mid);
}
}
}