JAVA拼手气领取红包金额算法

 

算法还存在如果红包金额数值很小的情况下,有小几率有的用户会分配0的情况,如有建议,还请大神赐教。

注意点 : 红包的金额/可领取人数>=min(最小分配的金额)

    public static void main(String[] args) {

        Double[] arr = new Double[10];
        BigDecimal totalMoney = new BigDecimal("0.2");
        int j = 0;
        for (int i = 10; i >= 1; i--, j++) {
            BigDecimal money = getRandomRedEnvelopeMoney(i, totalMoney);
            arr[j] = money.doubleValue();
            totalMoney = totalMoney.subtract(money);
        }
        System.out.println(Arrays.toString(arr));

        double sum = 0;
        System.out.println(arr.length);
        for (int i = 0; i < arr.length; i++) {

            sum += arr[i];
        }
        System.out.println(sum);

    }

    /**
     * 获取随机分配金额
     *
     * @param remainSize  剩余分配的个数
     * @param remainMoney 剩余分配的金额
     * @return java.math.BigDecimal
     * @throws
     * @author liuqiyu
     * @date 2019/4/3
     * <p>
     * 设置红包时,做验证    红包的金额/可领取人数>=min(最小分配的金额)
     */
    public static BigDecimal getRandomRedEnvelopeMoney(int remainSize, BigDecimal remainMoney) {

        // 随机分配的金额
        BigDecimal money;
        // 最小分配的金额 (元)  BigDecimal 防止科学计算,初始化时使用字符串创建
        BigDecimal min = new BigDecimal("0.01");
        // 最大分配金额
        BigDecimal max;
        // 判断红包金额/可领取的人数 与 每个人最小分配金额的对比
        int compare = remainMoney.divide(new BigDecimal(remainSize + ""), 2, BigDecimal.ROUND_DOWN).compareTo(min);
        // 小于
        if (compare < 0) {
            throw new RuntimeException("红包的金额/可领取人数小于最小分配金额");
        } else if (compare == 0) {
            return min;
        } else {
            if (remainSize == 1) {
                // System.out.println("最后一人获取:"+remainMoney);
                return remainMoney;
            }
            if (remainSize < 1) {
                return new BigDecimal(0);
            }
            // 计算可分配最大值
            max = remainMoney.subtract(min.multiply(new BigDecimal(remainSize)));

            int k = (remainSize) / 2;
            if (remainSize <= 2) {
                k = remainSize;
            }
            max = max.divide(new BigDecimal(k), 2, BigDecimal.ROUND_DOWN);
            // 计算可分配金额
            money = (min.multiply(new BigDecimal(100)).add(new BigDecimal(Math.random()).multiply(max.multiply(new BigDecimal(100)).subtract(min.multiply(new BigDecimal(100)).add(new BigDecimal(1))))));
            money = money.divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN);
            // remainMoney = remainMoney.subtract(money) ;
            // System.out.println("第" + remainSize + "个人拿到" + money + "剩下" + remainMoney);
            return money;
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值