简介

网上说的有两种比较公平的算法,一种是二倍均值法,一种是线段切割法。下面我们介绍下两种算法的实现:

二倍均值法

原理

剩余红包金额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元
以此类推,每次随机范围的均值是相等的
缺点:除了最后一次,任何一次抢到的金额都不会超过人均金额的两倍,并不是任意的随机

实现

//二倍均值法public static List<Integer> divideRedPackage(Integer totalAmount,Integer totalPeopleNum) {List<Integer> amountList = new ArrayList<Integer>();//为了使用random.nextInt(Integer)方法不得不先把红包金额放大100倍,最后在main函数里面再除以100//这样就可以保证每个人抢到的金额都可以精确到小数点后两位Integer restAmount = totalAmount * 100;Integer restPeopleNum = totalPeopleNum;Random random = new Random();for (int i = 0; i < totalPeopleNum - 1; i++) {// 随机范围:[1,剩余人均金额的两倍),左闭右开int amount = random.nextInt(restAmount / restPeopleNum * 2 - 1) + 1;restAmount -= amount;restPeopleNum--;amountList.add(amount);}amountList.add(restAmount);return amountList;}

线段切割法

原理

把红包总金额想象成一条很长的线段,而每个人抢到的金额,则是这条主线段所拆分出的若干子线段。

当N个人一起抢红包的时候,就需要确定N-1个切割点。

因此,当N个人一起抢总金额为M的红包时,我们需要做N-1次随机运算,以此确定N-1个切割点。

随机的范围区间是[1,100* M)。当所有切割点确定以后,子线段的长度也随之确定。这样每个人来抢红包的时候,只需要顺次领取与子线段长度等价的红包金额即可。

实现

 //线段分割法private static List<Integer> divide(double money, int n) {//验证参数合理校验//为了使用random.nextInt(Integer)方法不得不先把红包金额放大100倍,最后在main函数里面再除以100//这样就可以保证每个人抢到的金额都可以精确到小数点后两位int fen = (int) (money * 100);if (fen < n || n < 1) {System.out.println("红包个数必须大于0,并且最小红包不少于1分");}List<Integer> boards = new ArrayList<>();boards.add(0);boards.add(fen);//红包个数和板砖个数的关系while (boards.size() <= n) {int index = new Random().nextInt(fen - 1) + 1;if (boards.contains(index)) {//保证板子的位置不相同continue;}boards.add(index);}//计算每个红包的金额,将两个板子之间的钱加起来Collections.sort(boards);List<Integer> list = new ArrayList<>();for (int i = 0; i < boards.size() - 1; i++) {Integer e = boards.get(i + 1) - boards.get(i);list.add(e);}return list;}public static void main(String[] args) {
//        List<Integer> accountList = divideRedPackage(50, 1000);List<Integer> accountList = divide(50, 10);BigDecimal count = new BigDecimal(0);for (Integer amount : accountList) {//将抢到的金额再除以100进行还原BigDecimal tmpcount = new BigDecimal(amount).divide(new BigDecimal(100));count = count.add(tmpcount);System.out.println("抢到金额:" + tmpcount);}System.out.println("total=" + count);}

微信抢红包算法实现(JAVA)相关推荐

  1. 腾讯面试题:微信抢红包算法详解

    昨天在刷手机的时候看到毕导以前的一个视频,不知道大家有没有听说过毕导:清华大学化工博士,代表作品是:<微信红包先抢和后抢差距居然这么大>,百度百科如下: 博主昨天刷到的视频是毕导在某个平台 ...

  2. 看完微信抢红包算法你就明白,为啥你不是手气最佳

    本文分享自华为云社区<为啥春节抢红包总不是手气最佳?看完微信抢红包算法你就明白了!>,作者: XiaoLin_Java. 前言 春节必不可少的活动就是抢红包啦,从以前的纸质红包到现在互联网 ...

  3. matlab程序模拟微信抢红包,js模拟微信抢红包算法的讨论

    春节在家无聊,抢红包的时候想起来,不如自己写一个微信抢红包算法来练练手.本以为是非常简单的一个事情,但真正写下来也算是一波三折,不禁感叹,在程序员的路上,我还是太嫩了啊!写这篇文章的原因也是想与广大网 ...

  4. 微信,QQ抢红包算法(Java版)

    当我们平时在使用微信,QQ抢红包时,总会觉得很神奇,于是今天抽空研究了下其算法,然后参考了一些博客及自己的理解,写了一个算法. 规则: 1.所有人抢到金额之和等于红包金额,不能超过,也不能少于. 2. ...

  5. c++代码模拟微信抢红包算法,没人抢得过你!

    算法说明: 微信抢红包基本功能为:提示输入红包总金额和红包份数,保证每个红包的金额随机且不为0,每个红包的金额差距不能太大. 下面是一份C/C++学习资料,加小编C/C++学习群:825414254, ...

  6. java实现微信抢红包_GitHub - collection8899/RedPackage: java 实现仿照微信抢红包算法

    实现拼手气红包算法,有以下几个需要注意的地方: 抢红包的期望收益应与先后顺序无关 保证每个用户至少能抢到一个预设的最小金额,人民币红包设置的最小金额一般是0.01元,如果需要发其他货币类型的红包,比如 ...

  7. java 实现仿照微信抢红包算法,实测结果基本和微信吻合,附demo

    实现拼手气红包算法,有以下几个需要注意的地方: 抢红包的期望收益应与先后顺序无关 保证每个用户至少能抢到一个预设的最小金额,人民币红包设置的最小金额一般是0.01元,如果需要发其他货币类型的红包,比如 ...

  8. java开发微信抢红包挂_Java 实现仿照微信抢红包算法,实测结果基本和微信吻合,附demo...

    抢红包的期望收益应与先后顺序无关 保证每个用户至少能抢到一个预设的最小金额,人民币红包设置的最小金额一般是0.01元,如果需要发其他货币类型的红包,比如区块链货币或者积分,需要自定义一个最小金额. 所 ...

  9. 微信抢红包算法 java_java 实现仿照微信抢红包算法,实测结果基本和微信吻合,附demo...

    实现拼手气红包算法,有以下几个需要注意的地方: 抢红包的期望收益应与先后顺序无关 保证每个用户至少能抢到一个预设的最小金额,人民币红包设置的最小金额一般是0.01元,如果需要发其他货币类型的红包,比如 ...

最新文章

  1. 正数数组的最小不可组成和
  2. pip安装python包出错:ctype = ctype.encode(default_encoding) # omit in 3.x!
  3. J2SE核心开发实战(一)——认识J2SE
  4. NVIDIA GPU 架构梳理
  5. 马桶怎么清洗才干净无异味?
  6. TransferQueue实现线程通信
  7. MapReduce实现WordCount
  8. 一探究竟:box-sizing
  9. 安装Apache服务器
  10. 小白学python——函数1
  11. 为什么Service层要定义接口?
  12. 黑马程序员SpringBoot基础篇SSMP整合案例
  13. 什么原因导致了儿童自闭症?跟父母养育有关吗?
  14. linux运维实施命令,很实用的Linux运维命令
  15. 新式单片机视频教程下载
  16. 第六周 Java语法总结_设计原则_工厂模式_单例模式_代理模式(静态代理_动态代理)_递归_IO流_网络编程(UDP_TCP)_反射_数据库
  17. python画点连线_python matplotlib 在指定的两个点之间连线方法
  18. change lan.php lanid,天融信负载均衡本地文件包含漏洞
  19. Mac 终端的入门指南与进阶技巧
  20. 销售管理系统哪种好?

热门文章

  1. 网页版数据库管理工具安装教程——phpAdmin
  2. Windows远程连接电脑宿主机,管理服务器的几种快捷方式。
  3. 《软件工程实践》第五次作业-WordCount进阶需求 (结对第二次)
  4. ARGIS利用计算器对属性表数据进行编号
  5. 创建新Docker容器时出现“The container name /xxx is already in use by container xxxxxxxxxxx...”问题的解决办法
  6. TPTP—详细说明讲解
  7. 喜马拉雅主播工具软件:图片OCR文字识别自动转成mp3高品质语音文件
  8. 2017年EI收录的中国期刊目录
  9. 【定位问题】基于matlab TDOA+taylor算法移动基站无源定位【含Matlab源码 2098期】
  10. JavaSE基础(134) 打印流