1. 程式人生 > >實現微信紅包

實現微信紅包

模擬實現微信紅包

第一版

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;
    }
}