曾凡秩
(湖南工程职业技术学院 湖南长沙 410151)
微信红包算法分析及实现
曾凡秩
(湖南工程职业技术学院 湖南长沙 410151)
微信红包是现代生活中人们都非常喜欢的一项活动,在节假日、在聚会活动中,人们经常用发微信红包的方式来增加节假日和活的气氛。本文就微信红包的条件、生成算法、代码实现、红包验证进行了探讨。基本达到了微信红包的效果。
微信红包 随机红包算法 代码实现 红包验证
微信红包是现代生活中人们都非常喜欢的一项活动,在节假日、在聚会活动中,人们经常用发微信红包的方式来增加节假日和活动的气氛。微信红包有随机红包和普通红包,这里分析的是随机红包。
1.控制总量,就是红包总金额不超过给定的总金额。
2.控制个数,必须生成给定的红包个数。
3.每个红包的金额有下限,不能是0,至少是0.01元,即1分。
4.单个红包金额要不要设置某个上限。
5.每个红包的大小具有随机性,抽到大红包和小红包的机率相等。
6.红包总金额不少于红包个数*分。
比如100元,由10个人分,那么平均一个人是10元钱。然后付款后,系统开始预装红包:
第一份:系统由0~10元之间随机一个数,作为这一份的钱数,设hb1。
第二份:剩下的钱(100-hb1),系统由0~(100-hb1)/(10-1)随机一个数,作为这份的钱数,设hb2。
……
第n份:剩下的钱(100-hb1-hb2-...-hbn_1),作为这个份的钱数,设为hbn
通过前面的算法,你会发现,生成的最后一个红包总是最大的,为了防止总是最后一个人抽到最大红包。采取用户进来拿红包的时候,系统由0~9之间随机生成一个数,随机到几,就取第几份红包,然后将这个数存到peoplehb里,这样每个人拿到大红包的机会就均等了。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace wxhb
class Program
public static int hbNum = 10;//hbNum:红包数量
//判断数组A中是否存在数据x,存在返回true,不存在返回false
public static Boolean xInArr(int y,int[] a)
int i;
for(i = 0;i < hbNum;i++)
if(y == a[i])return true;
return false;
static void Main(string[] args)
//public Boolean xInArr(int y,int[] a);
float money=100;//money:红包总金额
int i;
float[] hb = new float[hbNum];
//hb:红包数组,保存每个红包事先随机分配的金额
float[] peoplehb=new float[hbNum];
Random r=new Random();
for(i=0;i if(money <= 0.01){ Console.Write("钱太少,不够分");return;} hb[i] =(float)(r.Next(0,(int)(money*100)))/100/(hbNum-i); if(hb[i] < 0.01)hb[i] = 0.01f; Console.Write("{0} , ",Math.Round(hb[i],2)); hb[hbNum - 1] = money;money = 0; Console.Write("{0} ",Math.Round(hb[i],2)); Console.WriteLine(); int[] pos = new int[hbNum]; int p,j; for(i = 0;i < hbNum;i++) pos[i] = -1; p = r.Next(0,hbNum); pos[0] = p; Console.Write("{0}, ",pos[0]); //按顺序从10个红包中随机抽一个红包,记录第i个红包位置pos[i] for(i = 1;i < hbNum;i++) p = r.Next(0,hbNum); while(xInArr(p,pos)) p=r.Next(0,hbNum); pos[i]=p; Console.Write("{0}, ",pos[i]); Console.WriteLine(); //按抽取顺序把红包大小显示出来 for(i = 0;i < hbNum;i++) Console.Write("{0}, ",Math.Round(hb[pos[i],2)); 运行第一次分配结果如下: 预装红包(10个):6.31 , 2.93 , 2.5 , 6.16 , 9.08 , 5.08 , 1.69 ,17.8 , 0.52 ,47.93 用户领到的红包顺序:1, 0, 8, 7, 5, 3, 4, 9, 6, 2 用户领取到的红包大小(10个):2.93, 6.31, 0.52, 17.8, 5.08,6.16, 9.08, 47.93, 1.69, 2.5 运行第二次分配结果如下: 预装红包(10个):8.89 , 6.25 , 4.96 , 7.16 , 9.05 , 1.49 , 15.01 ,11.08 , 3.98, 32.13 用户领到的红包顺序:5, 3, 0, 9, 4, 6, 7, 1, 2, 8, 用户领取到的红包大小(10个):1.49, 7.16, 8.89, 32.13, 9.05,15.01, 11.08, 6.25, 4.96, 3.98 运行第三次分配结果如下: 预装红包(10个):7.02 , 0.24 , 6.78 , 9.21 , 3.04 , 11.8 , 2.16 ,11.69 , 15.52, 32.55 用户领到的红包顺序:4, 8, 0, 7, 5, 9, 1, 2, 6, 3, 用户领取到的红包大小(10个):3.04, 15.52, 7.02, 11.69, 11.8,32.55, 0.24, 6.78, 2.16, 9.21 从运行结果来看,基本符合微信红包要求,且抽得大红包的机会也均等,与选抽取的先后顺序无关。 1.红包大小至少为1分。对应的代码为:if(hb[i] < 0.01)hb[i] = 0.01f; 也就是说,如果红包金额少于1分,则就要给定1分。 现给定金额为0.10,红包个数为10,运行程序分配结果如下: 预装红包(10个):0.01 , 0.01 , 0.01 , 0.01 , 0.01 , 0.01 , 0.01 ,0.01 , 0.01 ,0.01 用户领到的红包顺序:8, 3, 6, 1, 2, 7, 9, 5, 0, 4, 用户领取到的红包大小(10个):0.01, 0.01, 0.01, 0.01, 0.01,0.01, 0.01, 0.01, 0.01, 0.01 发现每个红包的金额为1分,与实际情况一致。 2.红包总金额转化为单位“分”后少于红包个数,则没法正常发红包。对应代码为:if(money <= 0.01){ Console.Write("钱太少,不够分");return;} 现给定金额为0.05,红包个数为10,运行程序结果如下: 1.代码可以进一步精减。 2.效率可以更一步提高,速度可以更快。 3.寻找更高速、快捷、有效的算法。 [1]安德森ASP NET高级编程, 清华大学出版社, 2002 [2] ASP NET程序设计基础与实训教程,清华大学出版社,2013 [3]Daniel Cazzulino等C#Web应用程序入门经典,清华大学出版社,2003四、运行程序进行验证
五、非正常情况验证
六、需要改进的地方