微信红包算法分析及实现

2016-11-08 08:51曾凡秩
新教育时代电子杂志(教师版) 2016年17期
关键词:清华大学出版社总金额个数

曾凡秩

(湖南工程职业技术学院 湖南长沙 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里,这样每个人拿到大红包的机会就均等了。

三、实现代码如下(在Visual Studio 2008用C#实现)

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

猜你喜欢
清华大学出版社总金额个数
怎样数出小正方体的个数
清华大学出版社期刊中心
等腰三角形个数探索
怎样数出小木块的个数
怎样数出小正方体的个数
Desperate Love towards the Dark Lady in Shakespeare’s Sonnets
《秘书工作手记》
哪些电影赔了钱
Translation and Dissemination of Critique of the Gotha Program in China in the Early Times〔* 〕
2013年6月中国铝合金车轮出口情况简析