抢红包算法

2023-04-15  本文已影响0人  爱学习的代代
题目: 小红在群里(15人)发了100元,10个的拼手气红包,如何实现?
image.png

一、题目分析

  1. 会有人抢不到,因为群人数大于了红包个数,需要考虑加🔐
  2. 如何更加合适的随机,多数人应该在10元左右
  3. 如果有人随机到了0,则取1分钱

二、代码构思

  1. 设计一个红包类
  2. 包含的属性应该有金额,个数,还有随机功能
  3. 实例方法,每次拆一个,返回拆得的金额

三、代码编写


package RedPackage;

import java.util.Random;

public class RedPackage {
    private int remainMoney;
    private int remainCount;
    private Random random;

    public RedPackage(int remainMoney, int remainCount) {
        this.remainMoney = remainMoney;
        this.remainCount = remainCount;
        this.random = new Random();
    }

    //获取下一个红包的值
    public int nextPackage() {

        if(this.remainCount == 1) {
            return this.remainMoney;
        }

        int currentMoney = Math.max(1, this.random.nextInt(this.remainMoney));
        this.remainMoney -= currentMoney;
        this.remainCount--;
        System.out.println(currentMoney);
        return currentMoney;


    }

}

测试代码:

package RedPackage;

public class RedPackageTest {
    public static void main(String[] args) {
        RedPackage redPackage = new RedPackage(100, 10);
        int sum = 0;
        int currentMoney;

        for(int i = 0; i<10; i++) {
            currentMoney = redPackage.nextPackage();
            System.out.println("currentMoney:  " + currentMoney);
            sum += currentMoney;
        }

        System.out.println("数据之和是:" + sum);
    }
}

代码测试:


image.png

执行后,发现报错了。分析一下前两次拆的金额过大,导致后面的人不够分了,出现了边界值为0的情况。

再次观察真实的微信拆红包的效果,其中最大的值是11.5大致在(0~100/16 * 2)的范围内,并不是之前考虑的每次都从剩余金额中随机。所以可以对程序做如下优化:

        int currentMoney = Math.max(1, this.random.nextInt(this.remainMoney / 10 * 2));

再次进行测试:


效果图1png 效果图2.png

发现剩余的总是比较多,还是有问题,this.remainMoney / 10 这里10不应该是定值,应该随着拆的剩余的红包个数变化而变化。

   int currentMoney = Math.max(1, this.random.nextInt(this.remainMoney /this.remainCount * 2));

测试效果如下:


image.png

最后转换成我们可以理解的方式输出

package RedPackage;

import java.math.BigDecimal;

public class RedPackageTest {
    public static void main(String[] args) {
        RedPackage redPackage = new RedPackage(100*100, 10);
        BigDecimal b = new BigDecimal(0);
        int currentMoney;

        for(int i = 0; i<10; i++) {
            currentMoney = redPackage.nextPackage();
            BigDecimal res = BigDecimal.valueOf(currentMoney);
            BigDecimal yuan = res.divide(BigDecimal.valueOf(100));
            System.out.println(yuan + "元");
            b = b.add(yuan); //BigDecimal的累加方式
        }

        System.out.println("数据之和是:" + b);
    }
}


运行结果


image.png
上一篇 下一篇

猜你喜欢

热点阅读