public class RedPacketTest {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
splitRedPacket(100.00, 7, 10.0, 30.0);
}
}
/**
* 每个数由最小值加上随机数,每次生成随机数由剩余的数减去随机数
*
* @param total 总和
* @param splitCount 分割的个数
* @param min 最小值
* @param max 最大值
*/
public static void splitRedPacket1(Double total, int splitCount, Double min, Double max) {
Double left = Double.parseDouble("" + (total - splitCount * min));
Random random = new Random();
DecimalFormat dcmFmt = new DecimalFormat("0.00");
Double num;
ArrayList<Double> list = new ArrayList<>();
do {
num = random.nextFloat() * left;
if (num < max - min && num > 0) {
//在差值之间
splitCount--;
if (splitCount == 0) {
num = left;
}
list.add(Double.parseDouble(dcmFmt.format(num + min)));
left = Double.parseDouble(dcmFmt.format(left - num));
}
} while (splitCount != 0);
//随机排序
Collections.shuffle(list);
System.out.println(Arrays.toString(list.toArray()));
Double sum = 0.0;
for (double x : list) {
sum = sum + x;
}
System.out.println("验证总和:" + dcmFmt.format(sum));
}
/**
* 判断个数奇偶,奇数先生成一个,剩下的配对,求出各队的总和,先随机生成一个,后由总数减去随机数
*
* @param total
* @param splitCount
* @param min
* @param max
*/
public static void splitRedPacket(Double total, int splitCount, Double min, Double max) {
ArrayList<Double> al = new ArrayList<>();
Random random = new Random();
DecimalFormat dcmFmt = new DecimalFormat("0.00");
// 奇数个红包,需要单独将其中一个红包先生成,以保证后续算法拆分份数为偶数。
if ((splitCount & 1) == 1) {
Double num = 0.0;
do {
num = random.nextDouble() * max;
} while (num >= max || num <= min);
total = Double.parseDouble(dcmFmt.format(total - num));
al.add(Double.parseDouble(dcmFmt.format(num)));
}
int couples = splitCount >> 1;
Double perCoupleSum = total / couples;
perCoupleSum = Double.parseDouble(dcmFmt.format(perCoupleSum));
for (int i = 0; i < couples; i++) {
Double num1 = 0.0;
Double num2 = 0.0;
do {
num1 = random.nextDouble() * max;
num2 = Double.parseDouble(dcmFmt.format(perCoupleSum - num1));
if (!al.contains(num1) && !al.contains(num2)) {
if (i == 0) {
num1 = (total - couples * perCoupleSum) + num1;
}
}
} while (num1 < min || num1 > max || num2 < min || num2 > max);
al.add(Double.parseDouble(dcmFmt.format(num1)));
al.add(Double.parseDouble(dcmFmt.format(num2)));
}
System.out.println("------------" + Arrays.toString(al.toArray()));
Double check_num = 0.0;
for (Double x : al) {
check_num = check_num + x;
}
System.out.println("验证总和:" + dcmFmt.format(check_num));
}
}