思路
为了不让最终生成的红包值多少相差太悬殊,先得到红包平均值,然后具体的红包值在这个平均值上下浮动,具体浮动多少由系统指定,注意该值范围在[0,平均数之间)
具体实现:
- 根据用户输入的总金额、总人数、浮动范围,求得红包上限和下限
- 先给每个红包中塞入平均值金额,并求得剩余金额
- 产生随机的红包值,范围在[0,浮动范围)
- 当剩余金额-随机的红包值>=0时:
随机往一个红包里面塞入随机的红包值,当原红包值+随机的红包值不大于上限里放进去,大于上限时,重新产生随机数 - 当剩余金额-随机的红包值<0时:
随机往一个红包里面塞入剩余金额,当红包值+剩余金额不大于上限里放进去,大于上限时重新产生随机数
代码实现
简单实现
public class HongBao {
//总钱数
private static int money = 100;
//总人数
private static int person = 7;
//上下浮动值,用来控制用户抢到红包的范围
// 让官方可以手动控制(手动输入),注意该值范围在[0,平均数之间)
private static int range = 4;
public static void main(String[] args) {
//理想情况下红包的平均值
int average = (int) (money / person);
//上限
int high = average + range;
//下限
int low = average - range;
ArrayList<Integer> data = new ArrayList<>();
//先让每个人分下限的红包数
for (int i = 0; i < person; i++) {
data.add(low);
}
//剩余金额
int shengYu = money - low * person;
int rand = (int) (Math.random() * (range) + 1);//产生[1,range]之间的随机数
//随机分配剩余的值
while (shengYu - rand >= 0) {
int index = (int) (Math.random() * (person)); //获取List下标
int tmp = data.get(index);
while (tmp + rand > high) { //如果红包总值小于等于最大值
index = (int) (Math.random() * (person )); //获取List下标
tmp = data.get(index);
}
data.set(index, tmp + rand);
shengYu = shengYu - rand;
//进行下一次循环
rand = (int) (Math.random() * (range) + 1);//产生[1,range]之间的随机数
}
//最后修正
if(shengYu - rand<0){
int index = (int) (Math.random() * (person)); //获取List下标
int tmp = data.get(index);
while (tmp + rand > high) { //如果红包总值小于等于最大值
index = (int) (Math.random() * (person )); //获取List下标
tmp = data.get(index);
}
data.set(index, tmp + shengYu);
}
//输出结果
int sum = 0;
for (int i = 0; i < person; i++) {
Integer t = data.get(i);
System.out.println(t);
sum += t;
}
System.out.println(sum);
}
}
优化后的代码
public class HongBao {
//总钱数
private static int money = 100;
//总人数
private static int person = 7;
//上下浮动值,用来控制用户抢到红包的范围
// 让官方可以手动控制(手动输入),注意该值范围在[1,平均数之间)
private static int range = 4;
public static void main(String[] args) {
//理想情况下红包的平均值
int average = (int) (money / person);
//上限
int high = average + range;
//下限
int low = average - range;
ArrayList<Integer> data = new ArrayList<>();
//先让每个人分下限的红包数
for (int i = 0; i < person; i++) {
data.add(low);
}
//剩余金额
int shengYu = money - low * person;
//随机分配剩余的值
boolean flag = true;
int rand = (int) (Math.random() * (range) + 1);//产生[1,range]之间的随机数
do{
int index = (int) (Math.random() * (person)); //获取List下标
int tmp = data.get(index);
while (tmp + rand > high) { //如果红包总值小于等于最大值
index = (int) (Math.random() * (person )); //获取List下标
tmp = data.get(index);
}
if(shengYu - rand<0){
data.set(index, tmp + shengYu);
flag = false;
}else {
data.set(index, tmp + rand);
}
shengYu = shengYu - rand;
//进行下一次循环
rand = (int) (Math.random() * (range) + 1);//产生[1,range]之间的随机数
}while (flag);
//输出结果
int sum = 0;
for (int i = 0; i < person; i++) {
Integer t = data.get(i);
System.out.println(t);
sum += t;
}
System.out.println(sum);
}
}