业务介绍

相信大家都用过微信发红包功能,如下图所示:

两个输入元素:

1、总金额 单位(元)
2、红包个数

假设输入总金额: 10,红包个数 6 ,大家可以试着发一个这样的红包看看,我相信每个人发出去的红包,分配的结果都会不一样,

以A,B,C三人的分配结果做一个示范

A的分配结果是:
1 ,1, 1, 1, 1, 5

B的分配结果是:
2,1, 1, 1, 2, 3

C的分配结果是:
1 ,2, 2, 2, 1, 2

其实真正的分配情况是各种各样的,有无数种的分配结果,这里举例只是大概说了下意思而已。

那么大家有没有思考这背后的分配算法是怎样的呢?

我有思考过这个问题,其实是可以从中找出一些规律出来,在这里分享下我的思考,还望指正。

必要条件:
1 首先每个红包得到最小金额数至少都是0.01 元(即1分)
2 其实红包的金额总数加起来肯定等于总金额

有了这两条先决条件,那就好办了

其实思路也很简单

第1步, 首先给每个红包塞入0.01 元,这样剩余总金额就等于 10 - 0.01 * 6
第2步,然后循环给每一个红包塞入不等的随机金额,每次塞完就将剩余金额减去已分配的金额,直到剩余金额=0为止,不再塞入为止

编码

有了上面思路,加上一点微调,就形成了如下的代码

package com.xyq.maventest.algorithm;import java.util.Arrays;
import java.util.Random;
/***** * @author youqiang.xiong* <p> 模拟微信发红包的算法封装* * </p>* 2018年2月25日下午8:04:19*/public class RedPacket {public static void main(String[] args) {// 微信红包拆分测试double money = 10;  //单位(元)int num = 6;System.out.println("总金额:"+money+"元\t 拆分红包总个数:" + num);int[]  array = divived(money,num);System.out.println("拆分后的各个红包金额数如下:");for (int i:array){System.out.print((double) i/100+"元\t");}}/***** 微信红包拆分方法* @param money  被拆分的总金额 (单位元)* @param n    被拆分的红包个数* @return  拆分后的每个红包金额数组*/public static int[] divived(double money, int n){int fen = (int) (money*100);if(fen < n || fen < 1){throw new IllegalArgumentException("被拆分的总金额不能小于1分");}// 创建一个长度等于n的红包数组int[] array = new int[n];//第一步 每个红包先塞1分Arrays.fill(array,1);//总金额减去已分配的n 分钱fen -= n;//第二步,循环遍历如果剩余金额>0 则一直分配int i = 0;  //从第一个红包进行分配//创建一个随机分配对象Random random = new Random();while (fen > 1){int f  = random.nextInt(fen);  //创建范围[0,fen)array[i++%n] +=  f;fen -= f;}//判断剩余未分配的金额是否大于0,如果大于0,可以把剩下未分配金额塞到第一个红包中if (fen > 0){array[0] +=  fen;}return array;}
}

效果

多次运行main方法,控制台每次打印的结果都不一样

第一次运行结果:

总金额:10.0元  红包总个数:6
拆分后的各个红包金额数如下:
5.11元   4.29元   0.26元   0.13元   0.08元   0.13元

第二次运行结果:

总金额:10.0元  拆分红包总个数:6
拆分后的各个红包金额数如下:
9.58元   0.38元   0.01元   0.01元   0.01元   0.01元

第三次运行结果:

总金额:10.0元  拆分红包总个数:6
拆分后的各个红包金额数如下:
9.58元   0.38元   0.01元   0.01元   0.01元   0.01元

第四次运行结果:

总金额:10.0元  拆分红包总个数:6
拆分后的各个红包金额数如下:
1.03元   0.2元    4.91元   3.74元   0.08元   0.04元

不管你多少次,基本上每次运行结果都会不一样。并且这里的分配的策略一定满足两个必要条件。

TODO

这边只是简陋的拥java程序的方式模拟了下红包拆分算法,如果大家有需要的可以把数据结果放到客户端进行展示(微信、app、浏览器等)

微信拼手气红包背后的算法逻辑相关推荐

  1. 微信拼手气红包C语言,微信拼手气红包背后的算法逻辑

    业务介绍 相信大家都用过微信发红包功能,如下图所示: 两个输入元素: 1.总金额 单位(元) 2.红包个数 假设输入总金额: 10,红包个数 6 ,大家可以试着发一个这样的红包看看,我相信每个人发出去 ...

  2. 微信拼手气红包算法(二倍平均值法)实现示范代码

    二倍平均值法 优势在于不需要先把每个人得多少算出来,只有拆红包的时候才会算出这个人得多少,减少实时算力 同时保证了每个人拼手气得到的平均值相同 设有10个人,红包总额100元. 100/10X2 = ...

  3. 模拟微信拼手气红包程序

    模拟微信拼手气红包程序 有用户输入总金额与红包数,随机给每个红包分配金额 package p03.t010;import java.util.Random; import java.util.Scan ...

  4. 微信手气红包算法 php,PHP实现微信/QQ手气红包,随机算法分享

    最近有个客户找我实现扫码抢手气红包,大家平时都在使用微信/QQ收发红包,玩的不亦乐乎.大家在抢红包,而程序员在研究红包算法.那么手气红包的随机分配算法是怎么实现的呢?怎么保证每个人都领得到,而且满足正 ...

  5. 微信拼手气红包C语言,微信拼手气红包算法分析

    好长一段时间了,身边的朋友都是在揣着手机一直在抢红包,都知道抢红包是一件非常有趣的事,还会有人因为抢红包手气差而生气,其实我们是不知道微信红包随机的算法,其实微信红包不单单是靠手气抢大小的,它中间藏着 ...

  6. 设计微信拼手气红包测试用例

    功能测试: 输入的金额数是否为有效字符.设计输入非法字符,例如输入".",粘贴其他汉字字符"一"等: 输入金额是否在有效范围内.设计输入超过左右金额数的边界,金 ...

  7. 二倍均值随机算法之抢拼手气红包场景应用

    拼手气类的游戏,更能激发用户购物和社交的趣味性,以及游戏竞争心理,拼手气类的活动甚至可以影响人们消费心理. 拼手气红包就是最简单的例子,哪怕你手气红包只有0.01元,在众多竞争者中脱颖而出,抢到的那一 ...

  8. java 红包算法_JAVA实现拼手气红包算法

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

  9. JAVA 拼手气红包 领取算法 记录

    废话不多说,直接上代码 //平分红包public static final Integer normalPacket = 1;//拼手气红包public static final Integer lu ...

最新文章

  1. 用Transformer完全替代CNN?
  2. TypeScript入门(三)面向对象特性
  3. python集合类型中的元素是有序的_Python基础-2-变量和数据类型(2)-列表、元组、字典、集合...
  4. 简单了解RestTemplate消息读取的转化
  5. 3_6 CommandMode 命令模式
  6. matlab编程实现二进制树搜索,数据结构: 二进制搜索树(用C语言实现)
  7. vim打开出现的文档^M什么
  8. 丰田pcs可以关闭吗_论安全性能,广汽丰田TNGA车型如何?
  9. typescript 与 js 开发 react 的区别
  10. 四叶草clover配置工具Clover Configurator 5 Ma汉化版
  11. 应用回归分析第五版pdf百度网盘_常用软件分享PDF转换word/excel/text等
  12. 基于STM32F1的HMC5883L电子罗盘驱动——妈妈从此再也不担心我迷路了
  13. 信用卡欺诈检测数据集
  14. Nginx区分PC或手机访问不同网站
  15. 联盛德 HLK-W806 (十三): 运行FatFs读写FAT和exFat格式的SD卡/TF卡
  16. 医疗险十大常见误区,你中了几个?
  17. ArcEngine编辑模块——将线段按距离、按比例分割成N条线段
  18. 如何给Eclipse进行汉化
  19. 算法度量方法——时间复杂度及空间复杂度
  20. PAT乙级【1001~1050】

热门文章

  1. (leetcode)1723. 完成所有工作的最短时间 -2021/5/8
  2. 为什么天蝎座出互联网大佬,我来告诉你原因!
  3. Android中的封装流式布局FlowLayout
  4. 高速接口----使用sfp完成以太网传输
  5. 使用Android Studio 查看内存泄漏
  6. 保存numpy数组到excel
  7. 基于MATLAB的运动模糊图像处理
  8. HQChart使用教程60-新版k线训练使用教程
  9. RESTful 架构风格概述(图文介绍)
  10. 识别车牌是什么神经网络,车牌识别深度神经网络