红包领取算法

12 篇文章 1 订阅

最近做红包业务,查了下网上的红包算法资料,整理出来一份自己记录下

领取的逻辑中心思想逻辑是:
每次领取的金额在 0.01和(剩余平均值*2)之间

import java.util.Random;

public class RedPackageUtil {
	/**
	 * remainSize 剩余的红包数量
     * remainMoney 剩余的钱
     */
    public static double getRandomMoney(Integer remainSize, Double remainMoney) {
        if (remainSize == 1) {
            double last = (double) Math.round(remainMoney * 100) / 100;
            System.out.println("最后一次抢到" + last + ", 剩余红包数量:" + remainSize-- + ", 剩余金额:" + (remainMoney - last));
            return last;
        }
        Random r = new Random();
        double min = 0.01; //
        double max = remainMoney / remainSize * 2;
        double money = r.nextDouble() * max;
        money = money <= min ? 0.01 : money;
        money = Math.floor(money * 100) / 100;
        remainSize--;
        remainMoney -= money;
        remainMoney = Math.floor(remainMoney * 100) / 100;
        System.out.println("本次抢到" + money + ", 剩余红包数量:" + remainSize + ", 剩余金额:" + remainMoney);
        getRandomMoney(remainSize, remainMoney);
        return money;
    }

    public static void main(String[] args) {
        RedPackageUtil.getRandomMoney(10, 100d);
    }

}

补一个BigDecimal版的

	/**
     * @param remainSize  剩余的红包数量
     * @param remainMoney  剩余的钱
     * @return
     */
    public static BigDecimal getRandomMoneyBigDecimal(Integer remainSize, BigDecimal remainMoney) {
        if (remainSize == 1) {
            BigDecimal last = remainMoney.setScale(2, BigDecimal.ROUND_DOWN);
            System.out.println("BigDecimal最后一次抢到" + last + ", 剩余红包数量:" + remainSize-- + ", 剩余金额:" + remainMoney.subtract(last));
            return last;
        }

        BigDecimal random = BigDecimal.valueOf(Math.random());
        BigDecimal min   = BigDecimal.valueOf(0.01);

        BigDecimal halfRemainSize = BigDecimal.valueOf(remainSize).divide(new BigDecimal(2), BigDecimal.ROUND_UP);
        BigDecimal max1 = remainMoney.divide(halfRemainSize, BigDecimal.ROUND_DOWN);
        BigDecimal minRemainAmount = min.multiply(BigDecimal.valueOf(remainSize - 1)).setScale(2, BigDecimal.ROUND_DOWN);
        BigDecimal max2 = remainMoney.subtract(minRemainAmount);
        BigDecimal max = (max1.compareTo(max2) < 0) ? max1 : max2;

        BigDecimal money = random.multiply(max).setScale(2, BigDecimal.ROUND_DOWN);
        money = money.compareTo(min) < 0 ? min: money;

        remainSize--;
        remainMoney = remainMoney.subtract(money).setScale(2, BigDecimal.ROUND_DOWN);
        System.out.println("BigDecimal本次抢到" + money + ", 剩余红包数量:" + remainSize + ", 剩余金额:" + remainMoney);
        getRandomMoneyBigDecimal(remainSize, remainMoney);
        return money;
    }


	public static void main(String[] args) {
	//        RedPackageUtil.getRandomMoney(25, 50d);
        RedPackageUtil.getRandomMoneyBigDecimal(25, new BigDecimal(50));
    }

大家可以复制自己执行一下试试,算法基本都是参考网上资料的,有问题欢迎指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值