java 紅包規則


java 紅包規則

拼手氣紅包:

規則:最大金額:全部金額/個數*倍數

最小金額:0.01

最后一個紅包是全部金額-領取金額

隨機分配

package com.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
 * 紅包分發工具類
 *
 */
public class CashRedPackUtils {
    /**
     * 一個紅包最少拆分數量
     */
    public static final int REDPACK_MIN_QUANTITY = 1;
    /**
     * 一個紅包最多拆分數量
     */
    public static final int REDPACK_MAX_QUANTITY = 100;
    /**
     * 小數位長度
     */
    private static final int SCALE = 2;
    /**
     * 舍棄的小數位處理方式
     */
    private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_EVEN;
    /**
     * 紅包放大倍數
     */
    private static final BigDecimal TIMES = new BigDecimal("3");
    /**
     * 單個紅包最小金額
     */
    public static final BigDecimal SINGLE_RED_MIN_MONEY = new BigDecimal("0.01");
    /**
     * 單個紅包最大金額
     */
//    private static final BigDecimal SINGLE_RED_MAX_MONEY = new BigDecimal("100");
    /**
     * 遞歸計算紅包金額時連續錯誤最大值,超過此次數將返回最小值
     */
    private static final int ERROR_MAX_NUM = 5;
    /**
     * 遞歸計算紅包金額連續錯誤次數初始值
     */
    private static final int ERROR_INIT_NUM = 1;
    /**
     * 計算金額時的小數位,1000代表3位小數
     */
    private static final int FRACTION_LENGTH = 1000;
    
    /**
     * 分發紅包
     * @param redMoney 紅包總金額
     * @param num 紅包數量
     * @return
     */
    public static List<BigDecimal> SplitRedPackes(BigDecimal redMoney, int num) {
        List<BigDecimal> redInfoList = new ArrayList<>();
    // 紅包有誤

    if(num < REDPACK_MIN_QUANTITY || num > REDPACK_MAX_QUANTITY)
       return redInfoList;

    //校驗:金額大於0 if(redMoney.compareTo(BigDecimal.ZERO) != 1) { return redInfoList; } if(num <= 1) { redInfoList.add(redMoney); return redInfoList; } Random random = new Random(); for(int i = 0; i < num; i++) { // System.out.println("\n" + (i+1) + "個紅包信息:"); int surplusNum = num - i;//未分配金額紅包數量 BigDecimal curRedMoney = fightLuckRedPacked(redMoney, surplusNum, random, ERROR_INIT_NUM); redInfoList.add(curRedMoney); redMoney = redMoney.subtract(curRedMoney); // MandoAssert.notTrue(redMoney.compareTo(BigDecimal.ZERO) == -1, "紅包金額有誤"); // System.out.println("紅包金額:" + curRedMoney + ",剩余:" + redMoney); } return redInfoList; } /** * 拼手氣紅包 * @param redMoney 紅包金額 * @param num 紅包數量 * @param random 隨機數生成對象 * @param errorNum 錯誤測試 * @return 單個紅包金額 */ private static BigDecimal fightLuckRedPacked(BigDecimal redMoney, int num, Random random, int errorNum) { if(num <= 1) { return redMoney; } if(errorNum > ERROR_MAX_NUM) { //隨機金額產生錯誤次數超過上限,返回最小值 return SINGLE_RED_MIN_MONEY; } //每個紅包最大金額 = 剩余總金額 / 未分配金額紅包數量 * 紅包放大倍數 int avgRedMaxMoney = redMoney.divide(new BigDecimal(num), ROUNDING_MODE).multiply(TIMES).intValue() * FRACTION_LENGTH; BigDecimal curRedMoney = new BigDecimal(random.nextInt(avgRedMaxMoney) * 1.00 / FRACTION_LENGTH + "").setScale(SCALE, ROUNDING_MODE); if(curRedMoney.compareTo(SINGLE_RED_MIN_MONEY) == -1) { //紅包最小值判斷:小於最小紅包金額,重新計算 return fightLuckRedPacked(redMoney, num, random, ++errorNum); } /*if(curRedMoney.compareTo(SINGLE_RED_MAX_MONEY) == 1) { //紅包最大值判斷 return fightLuckRedPacked(curRedMoney, num, random, ++errorNum); }*/ //最少保留紅包金額 BigDecimal surplusMinRedMoney = SINGLE_RED_MIN_MONEY.multiply(new BigDecimal(num - 1)); //除當前紅包剩余金額 BigDecimal surplusRedMoney = redMoney.subtract(curRedMoney); if(surplusMinRedMoney.compareTo(surplusRedMoney) == 1) { return fightLuckRedPacked(redMoney, num, random, ++errorNum); } return curRedMoney; } public static void main(String[] args) { System.out.println(SplitRedPackes(new BigDecimal("100"), 20)); } }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM