日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

隨機紅包算法,每個人都有自己的實現思路。

package com.jmmq.load.jim.algorithm;

import JAVA.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * 紅包算法
 */
public class RedPacketPrc {

    private static final BigDecimal MIN = new BigDecimal("0.01");

    public static void main(String[] args) {

        String[] rs = redPacketRandom(new BigDecimal(1), 100, false);
        BigDecimal sum = BigDecimal.ZERO;
        for(String str: rs){
            System.out.println(str);
            sum = sum.add(new BigDecimal(str));
        }
        System.out.println("sum:" + sum);

        System.out.println("(¯`•._.• •._.•´¯)(¯`•¸•´¯) (¯`•._.• •._.•´¯)(¯`•¸•´¯) (¯`•._.• •._.•´¯)(¯`•¸•´¯)");

        String[] res = redPacketOpen(new BigDecimal(20), 6, false);
        BigDecimal sum2 = BigDecimal.ZERO;
        for(String str: res){
            System.out.println(str);
            sum2 = sum2.add(new BigDecimal(str));
        }
        System.out.println("sum2:" + sum2);
    }

    /**
     *
     * @param faceValue 面值 單位:元
     * @param amount    人數
     * @param avgFlag 是否平均
     * @return
     *   平均分就不寫了
     *   思路一:
     *        按百分比進行隨機計算,最后一個進行匝差計算
     */
    public static String[] redPacketRandom(BigDecimal faceValue, int amount, boolean avgFlag){

        // 先計算平均數  四舍五入
        BigDecimal perValue = faceValue.divide(new BigDecimal(amount),3, BigDecimal.ROUND_HALF_UP);

        // 平均下來最小的紅包必須大于等于 1分錢
        if(perValue.compareTo(MIN) == -1){
            throw new RuntimeException("red packet amount OutOfBounds  min = 0.01");
        }

        String[] rs = new String[amount];

        // 平均
        if(avgFlag){
            // 這里四舍五入重新計算
            perValue = faceValue.divide(new BigDecimal(amount),2, BigDecimal.ROUND_HALF_UP);
            Arrays.fill(rs, perValue.toString());
            // 無法除盡
            if(perValue.multiply(new BigDecimal(amount)).compareTo(faceValue) != 0 ){
                // 隨機獲取一個下標
                int index = new Random().nextInt(amount);
                rs[index] = String.valueOf(new BigDecimal(rs[index]).add(
                           faceValue.subtract(perValue.multiply(new BigDecimal(amount)))));

            }
            return rs;
        }

        BigDecimal weightSum = BigDecimal.ZERO;
        BigDecimal redSum = BigDecimal.ZERO;
        BigDecimal[] weights = new BigDecimal[amount];
        // 隨機
        for (int i=0; i<rs.length; i++){
            BigDecimal seed = new BigDecimal(new Random().nextInt(amount));
            weightSum = weightSum.add(seed);
            weights[i] = seed;

            // 循環最后一個后計算金額
            if(i == rs.length -1){
                for(int j=0; j<rs.length; j++){
                   // 修改為向下取值,這樣差額永遠都是正數就不存在吃不掉差額的問題了
                   BigDecimal val = faceValue.multiply(weights[j].divide(weightSum,2, BigDecimal.ROUND_HALF_UP));
                   if(val.compareTo(MIN) == -1){
                       val = MIN;
                   }
                    redSum = redSum.add(val);
                   rs[j] = val.toString();
                }
            }
        }

        BigDecimal diff = faceValue.subtract(redSum);
        if(faceValue.compareTo(redSum) != 0){

            // 找到第一個加上或減少diff大于MIN的元素修改金額
            for(int i=0; i<rs.length; i++){
                if(new BigDecimal(rs[i]).add(diff).compareTo(MIN) > -1 ){
                    rs[i] = new BigDecimal(rs[i]).add(diff).toString();
                    break;
                }
            }
        }

        // 若沒有任何一個元素能吃掉差額,因此差額需要進行分攤了,
        // 這里簡單粗暴的將循環到大于MIN的都改為MIN同時減少差額
        // 這里代碼不進行優化,會寫另外一個優化的算法
        if(faceValue.compareTo(redSum) != 0){
            for(int i=0; i<rs.length; i++){
                if(new BigDecimal(rs[i]).compareTo(MIN) > 0){
                    if(new BigDecimal(rs[i]).add(diff).compareTo(MIN) > -1){
                        rs[i] = new BigDecimal(rs[i]).add(diff).toString();
                        break;
                    } else {
                        diff.add(new BigDecimal(rs[i])).subtract(MIN);
                        rs[i] = MIN.toString();
                    }
                }
            }
        }
        return rs;
    }


    /**
     *  上面算法進行優化
     * @param faceValue 面值 單位:元
     * @param amount    人數
     * @param avgFlag 是否平均
     * @return
     *   優化思路:
     *       上面算法為了保證紅包最小金額處理上花費了大量的循環來處理
     *       優化上就直接先分配最小金額,然后在進行隨機分攤剩余的錢
     */
    public static String[] redPacketOpen(BigDecimal faceValue, int amount, boolean avgFlag){

        // 先計算平均數  四舍五入
        BigDecimal perValue = faceValue.divide(new BigDecimal(amount),3, BigDecimal.ROUND_HALF_UP);

        // 平均下來最小的紅包必須大于等于 1分錢
        if(perValue.compareTo(MIN) == -1){
            throw new RuntimeException("red packet amount OutOfBounds  min = 0.01");
        }

        String[] rs = new String[amount];

        // 平均
        if(avgFlag){
            // 這里四舍五入重新計算
            perValue = faceValue.divide(new BigDecimal(amount),2, BigDecimal.ROUND_HALF_UP);
            Arrays.fill(rs, perValue.toString());
            // 無法除盡
            if(perValue.multiply(new BigDecimal(amount)).compareTo(faceValue) != 0 ){
                // 隨機獲取一個下標
                int index = new Random().nextInt(amount);
                rs[index] = String.valueOf(new BigDecimal(rs[index]).add(
                        faceValue.subtract(perValue.multiply(new BigDecimal(amount)))));

            }
            return rs;
        }

        // 隨機
        // 先把低保放進去
        Arrays.fill(rs, MIN.toString());

        BigDecimal weightSum = BigDecimal.ZERO;
        BigDecimal redSum = BigDecimal.ZERO;
        BigDecimal[] weights = new BigDecimal[amount];
        // 隨機
        for (int i=0; i<rs.length; i++){
            BigDecimal seed = new BigDecimal(new Random().nextInt(amount));
            weightSum = weightSum.add(seed);
            weights[i] = seed;

            // 循環最后一個后計算金額
            if(i == rs.length -1){
                for(int j=0; j<rs.length; j++){
                    BigDecimal val = faceValue.multiply(weights[j].divide(weightSum,2, BigDecimal.ROUND_DOWN));
                    redSum = redSum.add(val);
                    rs[j] = val.add(MIN).toString();
                }
            }
        }

        // 隨機獲取一個下標
        BigDecimal diff = faceValue.subtract(redSum);
        int index = new Random().nextInt(amount);
        rs[index] = String.valueOf(new BigDecimal(rs[index]).add(diff));

        return rs;
    }

}

分享到:
標簽:算法
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定