Java实现仿微信红包分配规则
程序员文章站
2024-03-08 19:13:46
最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。
算法介绍
一、红包金额...
最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。
算法介绍
一、红包金额限制
对于微信红包,我们知道没人随机的最小红包是1分,最大金额是200元,这里我们同样来设置红包的范围,下面代码我们统一金钱的单位为分。
//最小红包额度 private static final int minmoney = 1; //最大红包额度 private static final int maxmoney = 200 * 100;
二、判断红包金额是否合法
注意这一步伴随着整个算法,我们不仅要在分配红包之前要判断金额是否合法,同样要在每个人暂定随机金额后也要判断剩余的金额是否合法。
private boolean isright(int money, int count) { double avg = money / count; if (avg < minmoney) { return false; } if (avg > maxmoney) { return false; } return true; }
三、随机产生一个红包
这里我们采用随机的方式产生一个在minmoney和maxmoney之间的一个红包,产生红包之后,我们需要判断剩余的钱是否是合法红包,如果不是合法红包,我们就重新产生分配方案,在重新产生分配方案的时候,我们需要确定一个事情,是产生的红包过大还是过小,如果红包过大,下次就随机一个小值到本次红包金额的一个红包,如果红包金额过小,我们就产生一个红包金额到大值的一个红包。
private int random(int money, int mins, int maxs, int count) { //红包数量为1,直接返回金额 if (count == 1) { return money; } //如果最大金额和最小金额相等,直接返回金额 if (mins == maxs) { return mins; } int max = maxs > money ? money : maxs; //随机产生一个红包 int one = ((int)math.rint(math.random() * (max - mins) + mins)) % max + 1; int money1 = money - one; //判断该种分配方案是否正确 if (isright(money1, count -1)) { return one; } else { double avg = money1 / (count - 1); if (avg < minmoney) { //递归调用,修改红包最大金额 return random(money, mins, one, count); }else if (avg > maxmoney) { //递归调用,修改红包最小金额 return random(money, one, maxs, count); } } return one; }
四、实现红包分配
这里为了避免某一个红包占用大量资金,我们需要设定非最后一个红包的最大金额,我们把他设置为红包金额平均值的n倍;有了一、二、三中的方法,我们就可以来实现红包的分配了。
//每个红包最大是平均值的倍数 private static final double times = 2.1; public list<integer> splitredpackets(int money, int count) { if (!isright(money, count)) { return null; } list<integer> list = new arraylist<integer>(); //红包最大金额为平均金额的times倍 int max = (int) (money * times / count); max = max > maxmoney ? maxmoney : max; for (int i = 0; i < count; i++) { int one = random(money, minmoney, max, count - i); list.add(one); money -= one; } return list; }
红包分配方案评估
上面介绍了红包的基本算法,下面我们就对算法进行一次验证,假设有一个200元100份的红包,我们来看一下最后的分配方案。
完整代码
/** *@description: */ package com.lulei.weixin.util; import java.util.arraylist; import java.util.list; import com.lulei.util.jsonutil; public class redpacketutil { //最小红包额度 private static final int minmoney = 1; //最大红包额度 private static final int maxmoney = 200 * 100; //每个红包最大是平均值的倍数 private static final double times = 2.1; /** * @param money * @param count * @return * @author:lulei * @description: 拆分红包 */ public list<integer> splitredpackets(int money, int count) { if (!isright(money, count)) { return null; } list<integer> list = new arraylist<integer>(); //红包最大金额为平均金额的times倍 int max = (int) (money * times / count); max = max > maxmoney ? maxmoney : max; for (int i = 0; i < count; i++) { int one = random(money, minmoney, max, count - i); list.add(one); money -= one; } return list; } /** * @param money * @param mins * @param maxs * @param count * @return * @author:lulei * @description: 随机红包额度 */ private int random(int money, int mins, int maxs, int count) { //红包数量为1,直接返回金额 if (count == 1) { return money; } //如果最大金额和最小金额相等,直接返回金额 if (mins == maxs) { return mins; } int max = maxs > money ? money : maxs; //随机产生一个红包 int one = ((int)math.rint(math.random() * (max - mins) + mins)) % max + 1; int money1 = money - one; //判断该种分配方案是否正确 if (isright(money1, count -1)) { return one; } else { double avg = money1 / (count - 1); if (avg < minmoney) { //递归调用,修改红包最大金额 return random(money, mins, one, count); }else if (avg > maxmoney) { //递归调用,修改红包最小金额 return random(money, one, maxs, count); } } return one; } /** * @param money * @param count * @return * @author:lulei * @description: 此种红包是否合法 */ private boolean isright(int money, int count) { double avg = money / count; if (avg < minmoney) { return false; } if (avg > maxmoney) { return false; } return true; } public static void main(string[] args) { // todo auto-generated method stub redpacketutil util = new redpacketutil(); system.out.println(jsonutil.parsejson(util.splitredpackets(20000, 100))); } }
更多精彩内容请点击《android微信开发教程汇总》,《java微信开发教程汇总》欢迎大家学习阅读。
以上就是本文的全部内容,希望对大家学习java程序设计有所帮助。
下一篇: PHP编程计算日期间隔天数的方法