Java实现4种微信抢红包算法(小结)

目录
  • 概述
  • 一、剩余金额随机法
  • 二、二倍均值法(微信红包采用此法)
  • 三、整体随机法
  • 四、割线法

概述

14年微信推出红包功能以后,很多公司开始上自己的红包功能,到现在为止仍然有很多红包开发的需求,实现抢红包算法也是面试常考题。

要求:

  • 保证每个红包最少分得0.01元
  • 保证每个红包金额概率尽量均衡
  • 所有红包累计金额登于红包总金额

本文提供4中红包算法及Java代码实现demo,仅供参考。其中每种算法测试场景为:0.1元10个包,1元10个包,100元10个包,1000元10个包。

一、剩余金额随机法

以10元10个红包为例,去除每个红包的最小金额后,红包剩余9.9元;

  • 第一个红包在[0,9.9]范围随机,假设随机得1元,则第一个红包金额为1.1元,红包剩余8.9元。
  • 第二个红包在[0,8.9]范围随机,假设随机得1.5元,则第二个红包金额为1.6元,红包剩余7.4元。
  • 第三个红包在[0,7.4]范围随机,假设随机得0.5元,则第三个红包金额为0.6元,红包剩余6.9元。
  • 以此类推。
public static void main(String[] args) {
    //初始化测试场景
    BigDecimal[][] rrr = {
            {new BigDecimal("0.1"), new BigDecimal("10")},
            {new BigDecimal("1"), new BigDecimal("10")},
            {new BigDecimal("100"), new BigDecimal("10")},
            {new BigDecimal("1000"), new BigDecimal("10")}
    };
    BigDecimal min = new BigDecimal("0.01");
    //测试个场景
    for (BigDecimal[] decimals : rrr) {
        final BigDecimal amount = decimals[0];
        final BigDecimal num = decimals[1];
        System.out.println(amount + "元" + num + "个人抢=======================================================");
        test1(amount, min, num);
    }
}

private static void test1(BigDecimal amount, BigDecimal min, BigDecimal num) {
    BigDecimal remain = amount.subtract(min.multiply(num));
    final Random random = new Random();
    final BigDecimal hundred = new BigDecimal("100");
    BigDecimal sum = BigDecimal.ZERO;
    BigDecimal redpeck;
    for (int i = 0; i < num.intValue(); i++) {
        final int nextInt = random.nextInt(100);
        if (i == num.intValue() - 1) {
            redpeck = remain;
        } else {
            redpeck = new BigDecimal(nextInt).multiply(remain).divide(hundred, 2, RoundingMode.FLOOR);
        }
        if (remain.compareTo(redpeck) > 0) {
            remain = remain.subtract(redpeck);
        } else {
            remain = BigDecimal.ZERO;
        }
        sum = sum.add(min.add(redpeck));
        System.out.println("第" + (i + 1) + "个人抢到红包金额为:" + min.add(redpeck));
    }
    System.out.println("校验每个红包累计额度是否等于红包总额结果:" + (amount.compareTo(sum) == 0));
}

测试结果如下:可以看出此算法有明显缺陷,即:先领取的红包金额较大,后领取的红包金额较小,这就使得抢红包便的不公平。
0.1元10个人抢=======================================================
第1个人抢到红包金额为:0.01
第2个人抢到红包金额为:0.01
第3个人抢到红包金额为:0.01
第4个人抢到红包金额为:0.01
第5个人抢到红包金额为:0.01
第6个人抢到红包金额为:0.01
第7个人抢到红包金额为:0.01
第8个人抢到红包金额为:0.01
第9个人抢到红包金额为:0.01
第10个人抢到红包金额为:0.01
校验每个红包累计额度是否等于红包总额结果:true
1元10个人抢=======================================================
第1个人抢到红包金额为:0.09
第2个人抢到红包金额为:0.28
第3个人抢到红包金额为:0.19
第4个人抢到红包金额为:0.20
第5个人抢到红包金额为:0.15
第6个人抢到红包金额为:0.02
第7个人抢到红包金额为:0.03
第8个人抢到红包金额为:0.01
第9个人抢到红包金额为:0.01
第10个人抢到红包金额为:0.02
校验每个红包累计额度是否等于红包总额结果:true
100元10个人抢=======================================================
第1个人抢到红包金额为:19.99
第2个人抢到红包金额为:29.58
第3个人抢到红包金额为:38.27
第4个人抢到红包金额为:11.85
第5个人抢到红包金额为:0.11
第6个人抢到红包金额为:0.13
第7个人抢到红包金额为:0.01
第8个人抢到红包金额为:0.01
第9个人抢到红包金额为:0.03
第10个人抢到红包金额为:0.02
校验每个红包累计额度是否等于红包总额结果:true
1000元10个人抢=======================================================
第1个人抢到红包金额为:60.00
第2个人抢到红包金额为:695.54
第3个人抢到红包金额为:229.72
第4个人抢到红包金额为:8.95
第5个人抢到红包金额为:0.29
第6个人抢到红包金额为:4.64
第7个人抢到红包金额为:0.01
第8个人抢到红包金额为:0.69
第9个人抢到红包金额为:0.12
第10个人抢到红包金额为:0.04
校验每个红包累计额度是否等于红包总额结果:true

二、二倍均值法(微信红包采用此法)

还是以10元10个红包为例,去除每个红包的最小金额后,红包剩余9.9元,二倍均值计算公式:2 * 剩余金额/剩余红包数

  • 第一个红包在[0,1.98]范围随机,假设随机得1.9,则第一个红包金额为2.0,红包剩余8元。
  • 第二个红包在[0,2]范围随机,假设随机的1元,则第二个红包金额为1.1元,红包剩余7元。
  • 第三个红包在[0,2]范围随机,假设随机的0.5元,则第三个红包金额为0.6元,红包剩余5.5元。
  • 以此类推。
public static void main(String[] args) {
    //初始化测试场景
    BigDecimal[][] rrr = {
            {new BigDecimal("0.1"), new BigDecimal("10")},
            {new BigDecimal("1"), new BigDecimal("10")},
            {new BigDecimal("100"), new BigDecimal("10")},
            {new BigDecimal("1000"), new BigDecimal("10")}
    };
    BigDecimal min = new BigDecimal("0.01");
    //测试个场景
    for (BigDecimal[] decimals : rrr) {
        final BigDecimal amount = decimals[0];
        final BigDecimal num = decimals[1];
        System.out.println(amount + "元" + num + "个人抢=======================================================");
        test2(amount, min, num);
    }
}

private static void test2(BigDecimal amount,BigDecimal min ,BigDecimal num){
    BigDecimal remain = amount.subtract(min.multiply(num));
    final Random random = new Random();
    final BigDecimal hundred = new BigDecimal("100");
    final BigDecimal two = new BigDecimal("2");
    BigDecimal sum = BigDecimal.ZERO;
    BigDecimal redpeck;
    for (int i = 0; i < num.intValue(); i++) {
        final int nextInt = random.nextInt(100);
        if(i == num.intValue() -1){
            redpeck = remain;
        }else{
            redpeck = new BigDecimal(nextInt).multiply(remain.multiply(two).divide(num.subtract(new BigDecimal(i)),2,RoundingMode.CEILING)).divide(hundred,2, RoundingMode.FLOOR);
        }
        if(remain.compareTo(redpeck) > 0){
            remain = remain.subtract(redpeck);
        }else{
            remain = BigDecimal.ZERO;
        }
        sum = sum.add(min.add(redpeck));
        System.out.println("第"+(i+1)+"个人抢到红包金额为:"+min.add(redpeck));
    }
    System.out.println("校验每个红包累计额度是否等于红包总额结果:"+amount.compareTo(sum));
}

测试结果如下:此算法很好的保证了抢红包几率大致均等。
0.1元10个人抢=======================================================
第1个人抢到红包金额为:0.01
第2个人抢到红包金额为:0.01
第3个人抢到红包金额为:0.01
第4个人抢到红包金额为:0.01
第5个人抢到红包金额为:0.01
第6个人抢到红包金额为:0.01
第7个人抢到红包金额为:0.01
第8个人抢到红包金额为:0.01
第9个人抢到红包金额为:0.01
第10个人抢到红包金额为:0.01
校验每个红包累计额度是否等于红包总额结果:true
100元10个人抢=======================================================
第1个人抢到红包金额为:6.20
第2个人抢到红包金额为:7.09
第3个人抢到红包金额为:10.62
第4个人抢到红包金额为:18.68
第5个人抢到红包金额为:18.74
第6个人抢到红包金额为:2.32
第7个人抢到红包金额为:15.44
第8个人抢到红包金额为:5.43
第9个人抢到红包金额为:15.16
第10个人抢到红包金额为:0.32
校验每个红包累计额度是否等于红包总额结果:true
1元10个人抢=======================================================
第1个人抢到红包金额为:0.08
第2个人抢到红包金额为:0.05
第3个人抢到红包金额为:0.17
第4个人抢到红包金额为:0.17
第5个人抢到红包金额为:0.08
第6个人抢到红包金额为:0.06
第7个人抢到红包金额为:0.18
第8个人抢到红包金额为:0.10
第9个人抢到红包金额为:0.02
第10个人抢到红包金额为:0.09
校验每个红包累计额度是否等于红包总额结果:true
1000元10个人抢=======================================================
第1个人抢到红包金额为:125.99
第2个人抢到红包金额为:165.08
第3个人抢到红包金额为:31.90
第4个人抢到红包金额为:94.78
第5个人抢到红包金额为:137.79
第6个人抢到红包金额为:88.89
第7个人抢到红包金额为:156.44
第8个人抢到红包金额为:7.97
第9个人抢到红包金额为:151.01
第10个人抢到红包金额为:40.15
校验每个红包累计额度是否等于红包总额结果:true

三、整体随机法

还是以10元10个红包为例,随机10个数,红包金额公式为:红包总额 * 随机数/随机数总和,假设10个随机数为[5,9,8,7,6,5,4,3,2,1],10个随机数总和为50,

  • 第一个红包10*5/50,得1元。
  • 第二个红包10*9/50,得1.8元。
  • 第三个红包10*8/50,得1.6元。
  • 以此类推。
public static void main(String[] args) {
    //初始化测试场景
    BigDecimal[][] rrr = {
            {new BigDecimal("0.1"), new BigDecimal("10")},
            {new BigDecimal("1"), new BigDecimal("10")},
            {new BigDecimal("100"), new BigDecimal("10")},
            {new BigDecimal("1000"), new BigDecimal("10")}
    };
    BigDecimal min = new BigDecimal("0.01");
    //测试个场景
    for (BigDecimal[] decimals : rrr) {
        final BigDecimal amount = decimals[0];
        final BigDecimal num = decimals[1];
        System.out.println(amount + "元" + num + "个人抢=======================================================");
        test3(amount, min, num);
    }
}

private static void test3(BigDecimal amount,BigDecimal min ,BigDecimal num){
    final Random random = new Random();
    final int[] rand = new int[num.intValue()];
    BigDecimal sum1 = BigDecimal.ZERO;
    BigDecimal redpeck ;
    int sum = 0;
    for (int i = 0; i < num.intValue(); i++) {
        rand[i] = random.nextInt(100);
        sum += rand[i];
    }
    final BigDecimal bigDecimal = new BigDecimal(sum);
    BigDecimal remain = amount.subtract(min.multiply(num));
    for (int i = 0; i < rand.length; i++) {
        if(i == num.intValue() -1){
            redpeck = remain;
        }else{
            redpeck = remain.multiply(new BigDecimal(rand[i])).divide(bigDecimal,2,RoundingMode.FLOOR);
        }
        if(remain.compareTo(redpeck) > 0){
            remain = remain.subtract(redpeck);
        }else{
            remain = BigDecimal.ZERO;
        }
        sum1= sum1.add(min.add(redpeck));
        System.out.println("第"+(i+1)+"个人抢到红包金额为:"+min.add(redpeck));
    }

    System.out.println("校验每个红包累计额度是否等于红包总额结果:"+(amount.compareTo(sum1)==0));
}

测试结果如下:此算法随机性较大。
0.1元10个人抢=======================================================
第1个人抢到红包金额为:0.01
第2个人抢到红包金额为:0.01
第3个人抢到红包金额为:0.01
第4个人抢到红包金额为:0.01
第5个人抢到红包金额为:0.01
第6个人抢到红包金额为:0.01
第7个人抢到红包金额为:0.01
第8个人抢到红包金额为:0.01
第9个人抢到红包金额为:0.01
第10个人抢到红包金额为:0.01
校验每个红包累计额度是否等于红包总额结果:true
100元10个人抢=======================================================
第1个人抢到红包金额为:2.35
第2个人抢到红包金额为:14.12
第3个人抢到红包金额为:5.74
第4个人抢到红包金额为:6.61
第5个人抢到红包金额为:0.65
第6个人抢到红包金额为:10.97
第7个人抢到红包金额为:9.15
第8个人抢到红包金额为:7.93
第9个人抢到红包金额为:1.31
第10个人抢到红包金额为:41.17
校验每个红包累计额度是否等于红包总额结果:true
1元10个人抢=======================================================
第1个人抢到红包金额为:0.10
第2个人抢到红包金额为:0.02
第3个人抢到红包金额为:0.12
第4个人抢到红包金额为:0.03
第5个人抢到红包金额为:0.05
第6个人抢到红包金额为:0.12
第7个人抢到红包金额为:0.06
第8个人抢到红包金额为:0.01
第9个人抢到红包金额为:0.04
第10个人抢到红包金额为:0.45
校验每个红包累计额度是否等于红包总额结果:true
1000元10个人抢=======================================================
第1个人抢到红包金额为:148.96
第2个人抢到红包金额为:116.57
第3个人抢到红包金额为:80.49
第4个人抢到红包金额为:32.48
第5个人抢到红包金额为:89.39
第6个人抢到红包金额为:65.60
第7个人抢到红包金额为:20.77
第8个人抢到红包金额为:16.03
第9个人抢到红包金额为:36.79
第10个人抢到红包金额为:392.92
校验每个红包累计额度是否等于红包总额结果:true

四、割线法

还是以10元10个红包为例,在(0,10)范围随机9个间隔大于等于0.01数,假设为[1,1.2,2,3,4,5,6,7,8]

  • 第一个红包得1元
  • 第二个红包得0.2元
  • 第三个红得0.8元。
  • 以此类推。
public static void main(String[] args) {
    //初始化测试场景
    BigDecimal[][] rrr = {
            {new BigDecimal("0.1"), new BigDecimal("10")},
            {new BigDecimal("1"), new BigDecimal("10")},
            {new BigDecimal("100"), new BigDecimal("10")},
            {new BigDecimal("1000"), new BigDecimal("10")}
    };
    BigDecimal min = new BigDecimal("0.01");
    //测试个场景
    for (BigDecimal[] decimals : rrr) {
        final BigDecimal amount = decimals[0];
        final BigDecimal num = decimals[1];
        System.out.println(amount + "元" + num + "个人抢=======================================================");
        test3(amount, min, num);
    }
}

private static void test3(BigDecimal amount,BigDecimal min ,BigDecimal num){
    final Random random = new Random();
    final int[] rand = new int[num.intValue()];
    BigDecimal sum1 = BigDecimal.ZERO;
    BigDecimal redpeck ;
    int sum = 0;
    for (int i = 0; i < num.intValue(); i++) {
        rand[i] = random.nextInt(100);
        sum += rand[i];
    }
    final BigDecimal bigDecimal = new BigDecimal(sum);
    BigDecimal remain = amount.subtract(min.multiply(num));
    for (int i = 0; i < rand.length; i++) {
        if(i == num.intValue() -1){
            redpeck = remain;
        }else{
            redpeck = remain.multiply(new BigDecimal(rand[i])).divide(bigDecimal,2,RoundingMode.FLOOR);
        }
        if(remain.compareTo(redpeck) > 0){
            remain = remain.subtract(redpeck);
        }else{
            remain = BigDecimal.ZERO;
        }
        sum1= sum1.add(min.add(redpeck));
        System.out.println("第"+(i+1)+"个人抢到红包金额为:"+min.add(redpeck));
    }

    System.out.println("校验每个红包累计额度是否等于红包总额结果:"+(amount.compareTo(sum1)==0));
}

测试结果如下:此算法随机性较大,且性能不好
0.1元10个人抢=======================================================
第1个人抢到红包金额为:0.01
第2个人抢到红包金额为:0.01
第3个人抢到红包金额为:0.01
第4个人抢到红包金额为:0.01
第5个人抢到红包金额为:0.01
第6个人抢到红包金额为:0.01
第7个人抢到红包金额为:0.01
第8个人抢到红包金额为:0.01
第9个人抢到红包金额为:0.01
第10个人抢到红包金额为:0.01
校验每个红包累计额度是否等于红包总额结果:true
100元10个人抢=======================================================
第1个人抢到红包金额为:19.84
第2个人抢到红包金额为:2.73
第3个人抢到红包金额为:8.95
第4个人抢到红包金额为:14.10
第5个人抢到红包金额为:18.60
第6个人抢到红包金额为:3.66
第7个人抢到红包金额为:9.17
第8个人抢到红包金额为:15.49
第9个人抢到红包金额为:5.61
第10个人抢到红包金额为:1.85
校验每个红包累计额度是否等于红包总额结果:true
1元10个人抢=======================================================
第1个人抢到红包金额为:0.02
第2个人抢到红包金额为:0.28
第3个人抢到红包金额为:0.03
第4个人抢到红包金额为:0.02
第5个人抢到红包金额为:0.11
第6个人抢到红包金额为:0.23
第7个人抢到红包金额为:0.18
第8个人抢到红包金额为:0.09
第9个人抢到红包金额为:0.03
第10个人抢到红包金额为:0.01
校验每个红包累计额度是否等于红包总额结果:true
1000元10个人抢=======================================================
第1个人抢到红包金额为:69.28
第2个人抢到红包金额为:14.68
第3个人抢到红包金额为:373.16
第4个人抢到红包金额为:274.73
第5个人抢到红包金额为:30.77
第6个人抢到红包金额为:30.76
第7个人抢到红包金额为:95.55
第8个人抢到红包金额为:85.20
第9个人抢到红包金额为:10.44
第10个人抢到红包金额为:15.43
校验每个红包累计额度是否等于红包总额结果:true

到此这篇关于Java实现4种微信抢红包算法(小结)的文章就介绍到这了,更多相关Java 微信抢红包 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java实现微信抢红包算法

    简介 网上说的有两种比较公平的算法,一种是二倍均值法,一种是线段切割法.下面我们介绍下两种算法的实现: 二倍均值法 原理 剩余红包金额M,剩余人数N,那么:每次抢到金额=随机(0,M/N*2) 保证了每次随机金额的平均值是公平的 假设10人,红包金额100元 第一人:100/10*2=20,随机范围(0,20),平均可以抢到10元 第二人:90/9*2=20,随机范围(0,20),平均可以抢到10元 第三人:80/8*2=20,随机范围(0,20),平均可以抢到10元 以此类推,每次随机范围的均

  • java模拟微信抢红包的实例代码

    java简单模拟微信抢红包功能,本例发100元红包,有10个人抢,为了尽可能的公平,每个人的红包金额都要随机(保证结果的不确定性,本例抢红包的次序与红包金额匹配也随机),就是不能出现部分红包偏大部分偏小的情况,在区间0~100上随机生成9个节点,加0和100共11个节点按从小到大排序,各节点之间的差值就是红包金额,保证了红包金额之和等于100. public static void main(String[] args) { // 发100元红包,10人抢 // TODO Auto-genera

  • JAVA随机数随机字母的实现(微信抢红包小练习)

    今天我们谈一谈JAVA中的随机数 随机数 --Math.random() 0.0 在Math类中存在一个random()方法,用于产生随机数字,这个方法生成在0.0<=生成数<1.0 0.1那么它默认的生成的数显然在有些时候是满足不了我们的,我们来看看它的升级版 类型 返回值 (int)(Math.Random()*n) 0<=返回值<n m+(int)(Math.Random()*n) m<=返回值<m+n 随机数 --字母 0.2 使用Math类的random()

  • Java实现4种微信抢红包算法(小结)

    目录 概述 一.剩余金额随机法 二.二倍均值法(微信红包采用此法) 三.整体随机法 四.割线法 概述 14年微信推出红包功能以后,很多公司开始上自己的红包功能,到现在为止仍然有很多红包开发的需求,实现抢红包算法也是面试常考题. 要求: 保证每个红包最少分得0.01元 保证每个红包金额概率尽量均衡 所有红包累计金额登于红包总金额 本文提供4中红包算法及Java代码实现demo,仅供参考.其中每种算法测试场景为:0.1元10个包,1元10个包,100元10个包,1000元10个包. 一.剩余金额随机

  • Java实现5种负载均衡算法(小结)

    目录 概念 轮询算法 加权轮询法 加权随机法 随机法 IP_Hash算法 概念 负载均衡是将客户端请求访问,通过提前约定好的规则转发给各个server.其中有好几个种经典的算法,下面我们用Java实现这几种算法. 轮询算法 轮询算法按顺序把每个新的连接请求分配给下一个服务器,最终把所有请求平分给所有的服务器. 优点:绝对公平 缺点:无法根据服务器性能去分配,无法合理利用服务器资源. package com.monkeyjava.learn.basic.robin; import com.goog

  • 使用Java实现5种负载均衡算法实例

    目录 前言 概念 几种负载均衡算法图例 轮询算法 加权轮询法 加权随机法 随机法 IP_Hash算法 总结 前言 负载均衡是为了解决并发情况下,多个请求访问,把请求通过提前约定好的规则转发给各个server.其中有好几个种经典的算法.在用java代码编写这几种算法之前,先来了解一下负载均衡这个概念. 概念 负载均衡是将客户端请求访问,通过提前约定好的规则转发给各个server.其中有好几个种经典的算法,下面我们用Java实现这几种算法. 几种负载均衡算法图例 主要的负载均衡算法是图中这些,在代码

  • Java实现5种限流算法及7种限流方式

    目录 前言 1. 限流 2. 固定窗口算法 2.1. 代码实现 3. 滑动窗口算法 3.1. 代码实现 4. 滑动日志算法 4.1. 代码实现 5. 漏桶算法 6. 令牌桶算法 6.1. 代码实现 6.2. 思考 7. Redis 分布式限流 7.1. 固定窗口限流 7.3. 滑动窗口限流 8. 总结 参考 前言 最近几年,随着微服务的流行,服务和服务之间的依赖越来越强,调用关系越来越复杂,服务和服务之间的稳定性越来越重要.在遇到突发的请求量激增,恶意的用户访问,亦或请求频率过高给下游服务带来较

  • Java实现几种常见排序算法代码

    稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关键字R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前. 排序算法分类 常见的有插入(插入排序/希尔排序).交换(冒泡排序/快速排序).选择(选择排序).合并(归并排序)等. 一.插入排序 插入排序(Insertion Sort),它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),

  • JavaScript中几种常见排序算法小结

    说明 写这个主要是为了锻炼自己,并无实际意义. 每个浏览器测试得出的数据会不一样.比如我用chrome 测试 一般快速排序都会最快,IE 则根据数组长度有可能希尔最快. 不要用太大数据去测试冒泡排序(浏览器崩溃了我不管) 如果有兴趣可以 下载测试页面 个人理解 冒泡排序:最简单,也最慢,貌似长度小于7最优 插入排序: 比冒泡快,比快速排序和希尔排序慢,较小数据有优势 快速排序:这是一个非常快的排序方式,V8的sort方法就使用快速排序和插入排序的结合 希尔排序:在非chrome下数组长度小于10

  • JAVA实现简单抢红包算法(模拟真实抢红包)

    闲来无事,最近项目需求要写出用户登录首页来发现金红包,没有限额.我就自己稍微计算了一下如果有限额该怎么写.觉得这样与微信红包差不多.等项目需求完成以后.正好来博客贴一下我自己写的拆红包算法.个人觉得这个算法比较模拟现实抢红包规则.废话少说.先贴代码; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.ut

  • java实现抢红包算法(公平版和手速版)

    当我们在群里抢红包时真的是手速越快红包金额越大吗? 答案当然是并不是,都说了是拼手气,岂能是拼手速! 不过也可以有拼手速的方法 抢红包 二倍均值法(公平版) 线段切割法(手速版) 二倍均值法(公平版) 这是一种很合理很公平的抢红包算法了,绝对不会让你拼手速的,就别天真了. 在此我们假设 红包剩余金额为 M 红包剩余数量为 N 这种算法就是每次都在区间[0,M/N×2] 随机取一个数 假设100元红包发10个人,那么合理的做法应该是每个人领到10元的概率相同. 第一个人随机金额的范围为[0,100

随机推荐