红包随机分配的入参,一般只有两个,总金额与抢红包的总人数。难点是要保证在最后一个人抢完之前,不能让剩余钱包为空。所以要控制单人抢到红包钱数的最大值与最小值,并让这个值在剩余钱数之下。
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
public class WxReadPackets {
private final float MINVALUE = 0.01f;// 设定最小红包
private final float MAXVALUE = 200f;//设定红包最大值
public boolean isRight(float money,int count){
if(count<=0){
return false;
}
float avg = money/count;
if(avg<MINVALUE){
return false;
}
if(MAXVALUE<money){
return false;
}
return true;
}
/*
* 分红包算法(获得红包)
* */
public float randomPacket(float money, float minValue, float maxValaue, int count){
float maxMoney = 0; //定义随机分配区间最大值
if(count==1){ //判断是否为最后一次分配
return money;
}
if(minValue==maxValaue){ //如果最小值与最大值相等,则返回当前值
return money;
}
maxMoney = maxValaue>money?money:maxValaue; //获得随机分配最大区间
float one = (float) (Math.random()*(maxMoney-minValue)+minValue); //随机产生一个红包
float blance = money - one;
if(isRight(blance, count-1)){
return one;
}else{
float avg = blance/(count-1);
//如果本次分得的红包过大导致接下来没法继续分配....
if(avg<MINVALUE){
return randomPacket(money, minValue, one, count);
}else{
return randomPacket(money, one, maxValaue, count);
}
}
}
/**
* 分配红包
* @param money
* @param count
* @return
*/
@SuppressWarnings("finally")
public List<Object> spiltRedPacket(float money, int count) {
//判定红包金额是否合法
if(money<MINVALUE*count||money>MAXVALUE){
try {
throw new Exception("您输入的红包金额不合法!");
} catch (Exception e) {
e.printStackTrace();
}finally {
return null;
}
}
List<Object> list = new ArrayList<>();//创建红包集合
float max = money/count*4f; //防止某个红包占用大量资金,设定非最后一个红包的最大金额,把它设置成平均数的N倍;
max = max>money?money:max;
DecimalFormat decimalFormat = new DecimalFormat("0.00");//只取得小数点后两位数
//给个红包人数分配红包
for (int i = 0; i < count; i++) {
//保证红包的金额范围在minValue 与 max 之间
float randomRedPacket = randomPacket(money, MINVALUE, max, count - i);
String format = decimalFormat.format(randomRedPacket);
Float valueOf = Float.valueOf(format);
list.add(valueOf);
//将分配的金钱在剩余红包数中减少,同时减少分配人数
money -= valueOf;
}
return list;
}
/**
* 程序测试
* @param args
*/
@SuppressWarnings("unused")
public static void main(String[] args) {
WxReadPackets packet = new WxReadPackets();
List<Object> spiltRedPacket = packet.spiltRedPacket(100.00f, 10);
DecimalFormat decimalFormat = new DecimalFormat("0.00");
//打印返回的红包集合
for (int i = 0; i < spiltRedPacket.size(); i++) {
String format = decimalFormat.format(spiltRedPacket.get(i));
System.out.println(spiltRedPacket.get(i));
}
}
}