實現微信紅包
阿新 • • 發佈:2018-12-27
模擬實現微信紅包
第一版
package com.demo.hongbao;
import java.text.DecimalFormat;
import java.util.Random;
/**
* @ClassName: Main
* @Description: 模擬微信發紅包
*/
public class Main {
private static final DecimalFormat FORMAT = new DecimalFormat ("######.##");
private static final Random RANDOM = new Random();
public static void main(String[] args) {
String[] redPackage = getRedPackage(20, 11, 0);
for (String red : redPackage) {
double parseDouble = Double.parseDouble(red);
System.out.println(red) ;
}
}
/**
* @Title: getRedPackage
* @param: totalAmount:總金額
* @param: number:總人數
* @param: minAmount:每人最少的金額,預設為0.01
* @return: String[]
*/
private static String[] getRedPackage(double totalAmount, int number, double minAmount) {
minAmount = minAmount <= 0 ? 0.01 : minAmount;
// amount為隨機數種子=總金額-總人數*最少金額
double amount = totalAmount - number * minAmount;
if (totalAmount <= 0 || number < 1 || amount <= 0) {
throw new NumberFormatException("傳入引數有誤!");
}
String[] everyMoneys = new String[number];
for (int i = 0; i < everyMoneys.length; i++) {
if (amount > 0) {
//獲取amount範圍內的隨機數
String temp = FORMAT.format(RANDOM.nextDouble() * amount);
double parseDouble = Double.parseDouble(temp);
//將amount與最少金額相加,即某一個人的紅包金額
everyMoneys[i] = FORMAT.format(minAmount + parseDouble);
//用剩下的錢數,再算隨機數
amount -= parseDouble;
} else {
//說明隨機數種子已用完
everyMoneys[i] = "" + minAmount;
}
}
return everyMoneys;
}
}
問題
金額分配不夠均衡,前幾個人金額大,後幾個人卻很少。
出現原因:在通過種子獲取隨機數時,剛開始的種子數很大,越往後,種子數越小,最後種子數變為0時,剩餘的所有紅包全部為最小值。
第二版
package com.demo.hongbao;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* @ClassName: Main
* @Description: 模擬微信發紅包
*/
public class Main {
private static final DecimalFormat FORMAT = new DecimalFormat("######.##");
private static final Random RANDOM = new Random();
public static void main(String[] args) {
List<String> redPackage = getRedPackage(10, 20, 0.3);
for (String red : redPackage) {
System.out.println(red);
}
}
/**
* @Title: getRedPackage
* @param: totalAmount:總金額
* @param: number:總人數
* @param: minAmount:每人最少的金額,預設為0.01
* @return: String[]
*/
private static List<String> getRedPackage(double totalAmount, int number, double minAmount) {
if (totalAmount <= 0 || number < 1 || minAmount < 0) {
throw new NumberFormatException("傳入引數有誤!");
}
minAmount = minAmount == 0 ? 0.01 : minAmount;
List<String> everyMoneys = new ArrayList<>();
//最後一個人的紅包=總金額-其他人的紅包金額和。所以在迴圈時,去掉一個人,從1開始
for (int i = 1; i < number; i++) {
//剩餘的人數
int remainNumber = number - i;
//最少剩餘總金額:每個人至少都分最少的紅包金額後的剩餘金額
double totalMinAmount = minAmount * remainNumber;
//為了不出現紅包分配不均衡的情況,取隨機數時的上限為去掉最少剩餘總金額的平均數
double tempMax = (totalAmount - totalMinAmount) / remainNumber;
//計算隨機數,這個數就是一個紅包的金額
String temp = FORMAT.format(RANDOM.nextDouble() * (tempMax - minAmount) + minAmount);
everyMoneys.add(temp);
//總金額-這一次產生的金額,進入下次迴圈
totalAmount -= Double.parseDouble(temp);
}
//把最後一次的金額加到紅包列表中
everyMoneys.add(FORMAT.format(totalAmount));
return everyMoneys;
}
}