工作总结

2019-12-09  本文已影响0人  genglintong

背景

从去年开始到现在,参与一个新业务的研发。其中一个模块经过了多次优化升级,因此总结于此。
业务场景可以简化为,用户参与活动需要签到,活动的形式为多人一组,因此业务场景为在固定可签到时间内,将用户划分到最‘适合’的小组。

抽象

业务逻辑

 for (Map.Entry<String, Integer> entry : groupList.entrySet()) {
            // 组内已满 直接跳过
            if (entry.getValue() >= GroupEnum.GROUP_STU_NUM.getValue()) {
                continue;
            }
            // 初始化 或者 有更符合的小组 即替换
            if (targetGroup == null || targetGroup.getValue() < entry.getValue()) {
                targetGroup = entry;
            }
 }

但是,我们可以看到,由于现实场景,小组内人数是有限制的,且小组内人数为非负整数。于是,可以推理出,当小组人数达到 GROUP_STU_NUM - 1 时,即可退出。因此代码可优化为如下。

        for (Map.Entry<String, Integer> entry : groupList.entrySet()) {
            // 组内已满
            if (entry.getValue() >= GroupEnum.GROUP_STU_NUM.getValue()) {
                continue;
            }
            // 初始化 或者 有更符合的小组 即替换
            if (targetGroup == null || targetGroup.getValue() < entry.getValue()) {
                targetGroup = entry;
            }
            // 剪枝
            if (targetGroup.getValue() == GroupEnum.GROUP_STU_NUM.getValue() - 1) {
                break;
            }
        }
// 检测签到
if(!checkUserSign(uid)) {
    return;
}
// 这里还要检测该用户是否可以更换小组

// 判断小组已满
if(T.getNum() >= GROUP_STU_NUM) {
   return;
}

groupChange(uid, S, T);
// 1 获取需分配小组 - 即不满或不空的小组
List<Group> mergeList = getMergeList();

// 2 对需分配小组进行排序 - 按照组人数排倒序
sort(mergeList, DESC);

// 3. 首尾进行尝试合并
int start = 0 , end = mergeList.size() - 1;
while(start < end) {
      // 合并至 组人数超出时 将预合并组向前移动 至下一个人数少的预合并组
      if (mergeList[start].num + mergeList[end].num > GROUP_STU_NUM) {
            start++;
      }
      // 可以合并 将end 组合并至 start组
      mergeGroup(mergeList[start], mergeList[end]);
      // end 组已合并 向前移动
      end--;
}

// 4. 进行拆分小组
上一篇 下一篇

猜你喜欢

热点阅读