# 使用java进行红包分配算法

1、红包金额（最小精确到厘：0.001，数据库是用int表示，1元也就是1000厘）
2、红包发放数量
3、红包金额上限
4、红包金额下限
5、金额精度（精度可以理解为随机数能精确到小数哪一位，如范围为：0.01~0.5，如果精确到分的随机数为0.34 or 0.340，如果精确到厘：0.345）

1,2,3,4,5都可以由用户输入或选择，程序可进行判断是否参数不符计算，意思就是：

• 写回答

#### 3条回答默认 最新

• miaoch 2018-08-15 02:51
关注

我写了一个，但是感觉没那么满意

`````` public class Red {
private int remain;//金额，单位厘
private int count;//个数
private Precision precision;//精度
private int max;//上限，单位厘
private int min;//下限，单位厘
private int[] redPool;
private int index;

public static void main(String[] args) {
int count = 100;
Red red = Red.newInstance(10 * 1000, count, Precision.FEN, 1 * 1000, 5 * Precision.FEN.getPre());
int sum = 0;
for (int i = 0; i < count; i++) {
int money = red.getRed();
sum += money;
System.out.println(money);
}
System.out.println("---------------" + sum);
}

public int getRed() {
return index < count ? redPool[index++] : 0;
}

public static Red newInstance(int money, int count, Precision precision, int max, int min) {
Red red = new Red(money, count, precision, max, min);
String msg;
if ("".equals(msg = red.validate())) return red;
else throw new RuntimeException(msg);
}

private Red(int money, int count, Precision precision, int max, int min) {
this.remain = money;
this.count = count;
this.precision = precision;
this.max = max;
this.min = min;
init();
}

private void init() {
redPool = new int[count];
int remain_ = remain;
for (int i = 0; i < count - 1; i++) {
int max = getRealMax(remain_, count - i);
int min = getRealMin(remain_, count - i);
int money = ((int)(Math.random() * (max - min + precision.getPre())) + min)
/ precision.getPre() * precision.getPre();//[min, realMax]
remain_ -= money;
redPool[i] = money;
}
redPool[count - 1] = remain_;
randomPool();
}

private void randomPool() {
for (int i = 0; i < count; i++) {
int index = (int) (Math.random() * count);
int temp = redPool[i];
redPool[i] = redPool[index];
redPool[index] = temp;
}
}

private int getRealMax(int remain, int count) {
int calMax = remain - ((count - 1) * min);
return Math.min(calMax, max);
}

private int getRealMin(int remain, int count) {
int calMin = remain - ((count - 1) * max);
return Math.max(calMin, min);
}

public int getRemain() {
return remain;
}

public void setRemain(int remain) {
this.remain = remain;
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public int getMax() {
return max;
}

public void setMax(int max) {
this.max = max;
}

public int getMin() {
return min;
}

public void setMin(int min) {
this.min = min;
}

public Precision getPrecision() {
return precision;
}

public void setPrecision(Precision precision) {
this.precision = precision;
}

private String validate() {
String msg = "";
if (remain <= 0) {
msg = "余额不能为0";
} else if (remain % precision.getPre() != 0) {
msg = "余额的精度不对";
} else if (count <= 0) {
msg = "红包个数必须为正数";
} else if (max % precision.getPre() != 0) {
msg = "上限的精度不对";
} else if (max <= min) {
msg = "上限必须大于下限";
} else if (min % precision.getPre() != 0) {
msg = "下限的精度不对";
} else if (min <= 0) {
msg = "下限必须大于0";
} else if (getRealMax(remain, count) < getRealMin(remain, count)) {
msg = "上下限设置错误";
}
return msg;
}

}
enum Precision {
LI(1),
FEN(10),
JIAO(100),
YUAN(1000);

private int pre;
private Precision(int pre) {
this.pre = pre;
}
public int getPre() {
return pre;
}
}
``````
本回答被题主选为最佳回答 , 对您是否有帮助呢?
评论

#### 悬赏问题

• ¥15 visionmaster启动失败，提示为“机器不满足授权而被禁用”
• ¥50 用logisim设计16位单时钟周期cpu
• ¥15 IDEA中圈复杂度如何具体设置
• ¥50 labview采集不了数据
• ¥15 请上面代码做什么处理或什么混淆
• ¥15 英雄联盟自定义房间置顶
• ¥15 W5500网线插上无反应
• ¥15 如何用字典的Key，显示在WPF的xaml中
• ¥15 weautomate读取Excel表格信息然后填写到网页一直报错，如何解决？
• ¥15 C#如何在Webview2中获取网页验证码