Java实现仿微信红包分配规则_java

最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。

算法介绍

一、红包金额限制

      对于微信红包,我们知道没人随机的最小红包是1分,最大金额是200元,这里我们同样来设置红包的范围,下面代码我们统一金钱的单位为分。

//最小红包额度
private static final int MINMONEY = 1;
//最大红包额度
private static final int MAXMONEY = 200 * 100; 

二、判断红包金额是否合法
      注意这一步伴随着整个算法,我们不仅要在分配红包之前要判断金额是否合法,同样要在每个人暂定随机金额后也要判断剩余的金额是否合法。

private boolean isRight(int money, int count) {
 double avg = money / count;
 if (avg < MINMONEY) {
 return false;
 }
 if (avg > MAXMONEY) {
 return false;
 }
 return true;
}

三、随机产生一个红包
      这里我们采用随机的方式产生一个在MINMONEY和MAXMONEY之间的一个红包,产生红包之后,我们需要判断剩余的钱是否是合法红包,如果不是合法红包,我们就重新产生分配方案,在重新产生分配方案的时候,我们需要确定一个事情,是产生的红包过大还是过小,如果红包过大,下次就随机一个小值到本次红包金额的一个红包,如果红包金额过小,我们就产生一个红包金额到大值的一个红包。

private int random(int money, int minS, int maxS, int count) {
 //红包数量为1,直接返回金额
 if (count == 1) {
 return money;
 }
 //如果最大金额和最小金额相等,直接返回金额
 if (minS == maxS) {
 return minS;
 }
 int max = maxS > money ? money : maxS;
 //随机产生一个红包
 int one = ((int)Math.rint(Math.random() * (max - minS) + minS)) % max + 1;
 int money1 = money - one;
 //判断该种分配方案是否正确
 if (isRight(money1, count -1)) {
 return one;
 } else {
 double avg = money1 / (count - 1);
 if (avg < MINMONEY) {
  //递归调用,修改红包最大金额
  return random(money, minS, one, count);
 }else if (avg > MAXMONEY) {
  //递归调用,修改红包最小金额
  return random(money, one, maxS, count);
 }
 }
 return one;
}

四、实现红包分配
      这里为了避免某一个红包占用大量资金,我们需要设定非最后一个红包的最大金额,我们把他设置为红包金额平均值的N倍;有了一、二、三中的方法,我们就可以来实现红包的分配了。

//每个红包最大是平均值的倍数
private static final double TIMES = 2.1; 

public List<Integer> splitRedPackets(int money, int count) {
 if (!isRight(money, count)) {
 return null;
 }
 List<Integer> list = new ArrayList<Integer>();
 //红包最大金额为平均金额的TIMES倍
 int max = (int) (money * TIMES / count);
 max = max > MAXMONEY ? MAXMONEY : max;
 for (int i = 0; i < count; i++) {
 int one = random(money, MINMONEY, max, count - i);
 list.add(one);
 money -= one;
 }
 return list;
}

红包分配方案评估

      上面介绍了红包的基本算法,下面我们就对算法进行一次验证,假设有一个200元100份的红包,我们来看一下最后的分配方案。

完整代码

 /**
 *@Description:
 */
package com.lulei.weixin.util; 

import java.util.ArrayList;
import java.util.List; 

import com.lulei.util.JsonUtil; 

public class RedPacketUtil {
 //最小红包额度
 private static final int MINMONEY = 1;
 //最大红包额度
 private static final int MAXMONEY = 200 * 100;
 //每个红包最大是平均值的倍数
 private static final double TIMES = 2.1; 

 /**
 * @param money
 * @param count
 * @return
 * @Author:lulei
 * @Description: 拆分红包
 */
 public List<Integer> splitRedPackets(int money, int count) {
 if (!isRight(money, count)) {
 return null;
 }
 List<Integer> list = new ArrayList<Integer>();
 //红包最大金额为平均金额的TIMES倍
 int max = (int) (money * TIMES / count);
 max = max > MAXMONEY ? MAXMONEY : max;
 for (int i = 0; i < count; i++) {
 int one = random(money, MINMONEY, max, count - i);
 list.add(one);
 money -= one;
 }
 return list;
 } 

 /**
 * @param money
 * @param minS
 * @param maxS
 * @param count
 * @return
 * @Author:lulei
 * @Description: 随机红包额度
 */
 private int random(int money, int minS, int maxS, int count) {
 //红包数量为1,直接返回金额
 if (count == 1) {
 return money;
 }
 //如果最大金额和最小金额相等,直接返回金额
 if (minS == maxS) {
 return minS;
 }
 int max = maxS > money ? money : maxS;
 //随机产生一个红包
 int one = ((int)Math.rint(Math.random() * (max - minS) + minS)) % max + 1;
 int money1 = money - one;
 //判断该种分配方案是否正确
 if (isRight(money1, count -1)) {
 return one;
 } else {
 double avg = money1 / (count - 1);
 if (avg < MINMONEY) {
 //递归调用,修改红包最大金额
 return random(money, minS, one, count);
 }else if (avg > MAXMONEY) {
 //递归调用,修改红包最小金额
 return random(money, one, maxS, count);
 }
 }
 return one;
 } 

 /**
 * @param money
 * @param count
 * @return
 * @Author:lulei
 * @Description: 此种红包是否合法
 */
 private boolean isRight(int money, int count) {
 double avg = money / count;
 if (avg < MINMONEY) {
 return false;
 }
 if (avg > MAXMONEY) {
 return false;
 }
 return true;
 } 

 public static void main(String[] args) {
 // TODO Auto-generated method stub
 RedPacketUtil util = new RedPacketUtil();
 System.out.println(JsonUtil.parseJson(util.splitRedPackets(20000, 100)));
 }
} 

以上就是本文的全部内容,希望对大家学习java程序设计有所帮助。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索Java仿微信红包
Java红包分配规则
微信红包分配规则、红包随机分配算法、微信红包分配算法代码、java红包分配算法代码、红包分配算法,以便于您获取更多的相关知识。

时间: 2024-09-23 04:54:28

Java实现仿微信红包分配规则_java的相关文章

php仿微信红包分配算法的实现方法_php技巧

本文实例讲述了php仿微信红包分配算法的实现方法.分享给大家供大家参考,具体如下: /** * 红包分配:把一定金额随机分配给指定人数 * * @param int $money 用于分配的金额 * @param int $num 分配人数 */ function RandomMoney($money, $num) { echo "$money元随机分成$num份分别是:<br/>"; $remain=$money; $use=0; for ($i=1; $i<$nu

java制作仿微信视频播放控件_java

此控件继承自 SurfaceView,利用 MediaPlayer 播放视频. 小视频播放界面 MoviePlayerView.java import java.io.IOException; import android.content.Context; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListene

微信公众平台开发实战Java版之微信获取用户基本信息_java

在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的.对于不同公众号,同一用户的openid不同). 公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称.头像.性别.所在城市.语言和关注时间. 开发者可通过OpenID来获取用户基本信息.请使用https协议. 我们可以看看官方的文档:获取用户的基本信息. 接口调用请求说明  http请求方式: GET https://api.weixin.qq.com/cgi-

Java微信支付-微信红包_java

微信红包的使用已经很广泛,本篇文章介绍了微信发红包的实例,需要有认证的公众号,且开通了微信支付,商户平台且开通了现金红包的权限即可. https://pay.weixin.qq.com商户登陆地址.选择查看营销中心的现金红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1 现金红包的官网文档说明 先看几个图 简单的测试.前提需要你去商户平台先充值.不支持预支付.本文只是总结微信现金红包接口的调用与

PHP仿微信发红包领红包效果_php实例

近期项目需要在聊天的基础上新增红包功能,需求:仿微信(不含留言),但只能使用余额发红包.于是多次使用微信红包,了解各种交互界面及业务需求,如展示信息.分类(个人,群普通,群拼手气).个数限制(100).金额限制(200).过期时间(24小时)等等,然后着手开发,下面提及的基本全是提供给app端的接口,毕竟我是phper. 一.设计数据表如下 CREATE TABLE `red_packet` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `us

PHP仿微信发红包领红包效果

近期项目需要在聊天的基础上新增红包功能,需求:仿微信(不含留言),但只能使用余额发红包.于是多次使用微信红包,了解各种交互界面及业务需求,如展示信息.分类(个人,群普通,群拼手气).个数限制(100).金额限制(200).过期时间(24小时)等等,然后着手开发,下面提及的基本全是提供给app端的接口,毕竟我是phper. 一.设计数据表如下 CREATE TABLE `red_packet` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `us

微信支付java版V3验证数据合法性(Deom)_java

1.1 解析微信回调数据 InputStream inStream = request.getInputStream(); ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outSteam.write(buffer, 0, len); } o

Java抢红包的红包生成算法_java

马上过年了.过年微信红包很火,最近有个项目也要做抢红包,于是写了个红包的生成算法. 红包生成算法的需求 预先生成所有的红包还是一个请求随机生成一个红包 简单来说,就是把一个大整数m分解(直接以"分为单位,如1元即100)分解成n个小整数的过程,小整数的范围是[min, max]. 最简单的思路,先保底,每个小红包保证有min,然后每个请求都随机生成一个0到(max-min)范围的整数,再加上min就是红包的钱数. 这个算法虽然简单,但是有一个弊端:最后生成的红包可能都是min钱数的.也就是说可能

Android仿微信菜单(Menu)(使用C#和Java分别实现)_Android

本篇是对安卓菜单使用编程方式实现,当然可以使用XML的方式完成同样的功能,基本Java和C#写法都是一致的,所以使用XML的方式在本篇中使用Java演示,需要注意的是,对于如果不是VS开发的话,那么资源文件名称必须以小写开头,否则会报错. 运行效果 C#实现 using Android.App; using Android.OS; using Android.Views; using Android.Widget; namespace MenuDemo { [Activity(Label = "