Java模拟微信红包分配算法

**

 * Java模拟微信红包分配算法(还有点问题,明天优化一下)

 * @author Administrator
 *
 */
public class Demo10 {


/*
* 1.红包总结不超过200*100,单位(分)
* 2.每个红包都要有钱,最低不能低于1分
*/
private static final int MINMONEY=1;
private static final int MAXMONEY=200*100;
/*
* 为了避免某个红包占用大量金额,需要设定非最后一个红包的最大金额,设置为
* 红包金额的N倍
*/
private static final double TIMES=2.1;
/**
* 拆分红包
* @param money:红包总金额
* @param count:个数
* @return
*/
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 = randomRedPacket(money,MINMONEY,max,count-1);
list.add(one);
money-=one;
}
return list;

}
private int randomRedPacket(int money, int minS, int maxS, int count) {
//若是只有一个红包,直接返回
if(count==1){
return maxS;
}
//若是最小金额红包==最大金额红包,直接返回最小金额红包
if(minS==maxS){
return minS;
}
//校验最大值max要是比money的金额多的话,去money的金额
int max = maxS>money?money:maxS;
//随机一个红包=随机一个数*(金额-最小)+最小
int one =((int)Math.rint(Math.random()*(max-minS)+minS)); 
//剩下的金额
int moneyOther = money-one;
//校验这种随机方案是否可行,不合法的话,就要重新分配方案
if(!isRight(moneyOther,count-1)){
return one;
}else{
//重新分配
double avg = moneyOther/(count-1);
//本次红包过大,导致下次的红包过小;如果红包过大,
//下次就随机一个小值到本次红包金额的一个红包  
if(avg<MINMONEY){
//递归调用,修改红包最大金额;
return randomRedPacket(money,one,maxS,count);
}else if(avg>MAXMONEY){
return randomRedPacket(money,one,maxS,count);
}
}
return one;
}

private boolean isRight(int money, int count) {
double avg = money/count;
//小于最小金额
if(avg<MINMONEY){
return false;
}else if(avg>MAXMONEY){
return false;
}
return true;
}
public static void main(String[] args) {
Demo10 dd = new Demo10();
System.out.println(dd.splitRedPackets(120,6));
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值