前言:
之前用的是最暴力的方式来实现的,也就是四个复选框写四层循环。
但是我也太low了把。。。
这个实际上就是一个笛卡儿积的运算。
先说一下需求,
质检是有规则的,比如有一个比例。
然后根据城市和年龄还有产品渠道 能够得到一条确定的规则,如果配置了规则的话。
那么,如果在前端勾选规则,
["天津","北京"]*["营销渠道","xx渠道"]*["60岁","40岁"]*["一号产品","二号产品"]
实际上穿得是编号,在这种业务需求里面,把上述条件配置了百分之20比如。
那么这应该是一种Key value的一种形式,并不该用MYSQL来存这种关系。
那么得到所有条件的数组就是第一步操作,之后使用redis来存放就好了。
笛卡尔积的算法,实际上每家公司都是一样的。
对于2B的业务来说,怎么样灵活动态才是体现一个程序员的价值的标准,否则来一家公司就给自己添堵了。。
后续重构这部分业务吧。我是真的没人带,这也太难了。
笛卡儿积的实现代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class CartesianArith {
public static <T> List<List<T>> cartesianProduct(T[]... sets) {
if (sets == null || sets.length == 0) {
return Collections.emptyList();
}
int total = 1;
//声明进位指针cIndex
int cIndex = sets.length - 1;
//声明counterMap(角标 - counter)
int[] counterMap = new int[sets.length];
for (int i = 0; i < sets.length; i++) {
counterMap[i] = 0;
total *= (sets[i] == null || sets[i].length == 0 ? 1 : sets[i].length);
}
List<List<T>> rt = new ArrayList<>(total);
//开始求笛卡尔积
while (cIndex >= 0) {
List<T> element = new ArrayList<>(sets.length);
for (int j = 0; j < sets.length; j++) {
T[] set = sets[j];
//忽略空集
if (set != null && set.length > 0) {
element.add(set[counterMap[j]]);
}
//从末位触发指针进位
if (j == sets.length - 1) {
if (set == null || ++counterMap[j] > set.length - 1) {
//重置指针
counterMap[j] = 0;
//进位
int cidx = j;
while (--cidx >= 0) {
//判断如果刚好前一位也要进位继续重置指针进位
if (sets[cidx] == null || ++counterMap[cidx] > sets[cidx].length - 1) {
counterMap[cidx] = 0;
continue;
}
break;
}
if (cidx < cIndex) {
//移动进位指针
cIndex = cidx;
}
}
}
}
if (element.size() > 0) {
rt.add(element);
}
}
return rt;
}
public static void main(String[] args) {
System.out.println(Arrays.deepToString(
cartesianProduct(
new String[]{"0", "1"}, new String[]{"0", "1", "2"}, new String[]{"0", "1", "2"}
).toArray()));
}
}
笛卡尔积算法
转自:https://blog.csdn.net/m0_38043362/article/details/80944879