Java: 微信红包分配实现
来源:互联网 发布:广工数据挖掘试卷 编辑:程序博客网 时间:2024/06/05 00:40
前阵子app里需要实现抢红包的功能,后台需要个红包分配的算法,于是搜了下找到了实现的主要思想,参考文章http://blog.csdn.net/forever_cvank/article/details/54693000感谢博主的分享。
基本思想就是根据当前剩余金额和人数得到平均值,然后随机,为了防止最后的人分得最大金额需要调整平均值的倍数,这样就会导致后面红包不够分,于是就处理成如果不够分则按照正常的平均值进行随机,所以这个算法的弱点就是越到后面越抢不到大金额的红包,下面上代码
public class TestRedPackage { //红包最小值 private static final BigDecimal MINVALUE = new BigDecimal("0.01"); //红包最大值 private static final BigDecimal MAXVALUE = new BigDecimal("200"); //这里为了避免某一个红包占用大量资金,我们需要设定非最后一个红包的最大金额,我们把他设置为红包金额平均值的N倍 private static final BigDecimal TIMES = new BigDecimal("2.1"); //小数点位数 private static final int MAX_DIGIT = 2; private static void test(BigDecimal money, int people) { List<BigDecimal> result = spiltRedPackets(money, people); } /** * 分红包 * * @param money * @param count * @return */ public List<BigDecimal> spiltRedPackets(BigDecimal money, int count) { //首先判断红包是否合情理 if (!isRight(money, count)) { return null; } List<BigDecimal> list = new ArrayList<>(); BigDecimal average = money.divide(new BigDecimal(count), MAX_DIGIT, BigDecimal.ROUND_UP); BigDecimal max = TIMES.multiply(average).setScale(MAX_DIGIT, BigDecimal.ROUND_UP); max = max.compareTo(money) > 0 ? money : max; for (int i = 0; i < count; i++) { BigDecimal value = randomRedPacket(money, MINVALUE, max, count - i); list.add(value); money = money.subtract(value); } return list; } /** * 分红包核心算法 * * @param money * @param minS * @param maxS * @param count * @return */ public BigDecimal randomRedPacket(BigDecimal money, BigDecimal minS, BigDecimal maxS, int count) { //当人数剩余一个时,把当前剩余全部返回 if (count == 1) { return money; } //如果当前最小红包等于最大红包,之间返回当前红包 if (minS.compareTo(maxS) == 0) { return minS; } BigDecimal max = maxS.compareTo(money) > 0 ? money : maxS; //随机产生一个红包 BigDecimal range = max.subtract(minS); BigDecimal randomNumner = new BigDecimal(Math.random()).setScale(MAX_DIGIT, BigDecimal.ROUND_HALF_UP); BigDecimal randomResult = range.multiply(randomNumner).setScale(MAX_DIGIT, BigDecimal.ROUND_UP); BigDecimal one = randomResult.add(minS); BigDecimal balance = money.subtract(one); //判断此次分配后,后续是否合理 if (isRight(balance, count - 1)) { return one; } else { //重新分配 BigDecimal avg = balance.divide(new BigDecimal(count - 1), 10, BigDecimal.ROUND_UP); //本次红包过大,导致下次的红包过小;如果红包过大,下次就随机一个小值到本次红包金额的一个红包 if (avg.compareTo(MINVALUE) < 0) { //递归调用,修改红包最大金额 BigDecimal average = money.divide(new BigDecimal(count), MAX_DIGIT, BigDecimal.ROUND_UP); return randomRedPacket(money, minS, average, count); } else { //递归调用,修改红包最小金额 return randomRedPacket(money, one, maxS, count); } } } /** * 判断红包是否合情理 * * @param money * @param count * @return */ public boolean isRight(BigDecimal money, int count) { if (count <= 0 || money == null || money.compareTo(BigDecimal.ZERO) <= 0) { return false; } BigDecimal avg = money.divide(new BigDecimal(count), 10, BigDecimal.ROUND_UP); //防止舍入造成误差 if (avg.compareTo(MINVALUE) < 0) { return false; } else if (avg.compareTo(MAXVALUE) > 0) { return false; } return true; }}
阅读全文
0 0
- Java 实现微信红包分配算法
- java实现微信红包分配算法
- java实现微信红包分配改进
- Java: 微信红包分配实现
- Java仿实现微信红包分配算法
- Java仿实现微信红包分配算法
- Java仿实现微信红包分配算法
- 模拟微信分配红包
- 微信红包高级接口JAVA实现
- java实现微信红包随机算法
- 微信红包随机分配算法初探
- 微信红包的分配秘密
- 微信红包金额分配的算法
- 微信红包实现原理
- 微信红包实现原理
- 微信红包接口实现
- 微信红包实现原理
- JAVA实现仿微信红包分配规则
- How do CUDA blocks/warps/threads map onto CUDA cores?
- Linux中vim的命令备忘录
- F
- 穷举n位二进制
- HDU2045 LELE的RPG难题
- Java: 微信红包分配实现
- 搜索学习基础--代码模拟倒排索引过程
- spring+springMVC+mybatis整合搭建crud项目日记
- HDU 1166 排兵布阵(树状数组)
- JavaScript中如何使用原型方法--prototype
- SSM框架
- 每天一道LeetCode-----获取无重复项/有重复项序列的全排列
- 新手常见Python错误
- 从一道题看四边形不等式