曾凡秩
(湖南工程職業(yè)技術(shù)學(xué)院 湖南長(zhǎng)沙 410151)
微信紅包算法分析及實(shí)現(xiàn)
曾凡秩
(湖南工程職業(yè)技術(shù)學(xué)院 湖南長(zhǎng)沙 410151)
微信紅包是現(xiàn)代生活中人們都非常喜歡的一項(xiàng)活動(dòng),在節(jié)假日、在聚會(huì)活動(dòng)中,人們經(jīng)常用發(fā)微信紅包的方式來增加節(jié)假日和活的氣氛。本文就微信紅包的條件、生成算法、代碼實(shí)現(xiàn)、紅包驗(yàn)證進(jìn)行了探討?;具_(dá)到了微信紅包的效果。
微信紅包 隨機(jī)紅包算法 代碼實(shí)現(xiàn) 紅包驗(yàn)證
微信紅包是現(xiàn)代生活中人們都非常喜歡的一項(xiàng)活動(dòng),在節(jié)假日、在聚會(huì)活動(dòng)中,人們經(jīng)常用發(fā)微信紅包的方式來增加節(jié)假日和活動(dòng)的氣氛。微信紅包有隨機(jī)紅包和普通紅包,這里分析的是隨機(jī)紅包。
1.控制總量,就是紅包總金額不超過給定的總金額。
2.控制個(gè)數(shù),必須生成給定的紅包個(gè)數(shù)。
3.每個(gè)紅包的金額有下限,不能是0,至少是0.01元,即1分。
4.單個(gè)紅包金額要不要設(shè)置某個(gè)上限。
5.每個(gè)紅包的大小具有隨機(jī)性,抽到大紅包和小紅包的機(jī)率相等。
6.紅包總金額不少于紅包個(gè)數(shù)*分。
比如100元,由10個(gè)人分,那么平均一個(gè)人是10元錢。然后付款后,系統(tǒng)開始預(yù)裝紅包:
第一份:系統(tǒng)由0~10元之間隨機(jī)一個(gè)數(shù),作為這一份的錢數(shù),設(shè)hb1。
第二份:剩下的錢(100-hb1),系統(tǒng)由0~(100-hb1)/(10-1)隨機(jī)一個(gè)數(shù),作為這份的錢數(shù),設(shè)hb2。
……
第n份:剩下的錢(100-hb1-hb2-...-hbn_1),作為這個(gè)份的錢數(shù),設(shè)為hbn
通過前面的算法,你會(huì)發(fā)現(xiàn),生成的最后一個(gè)紅包總是最大的,為了防止總是最后一個(gè)人抽到最大紅包。采取用戶進(jìn)來拿紅包的時(shí)候,系統(tǒng)由0~9之間隨機(jī)生成一個(gè)數(shù),隨機(jī)到幾,就取第幾份紅包,然后將這個(gè)數(shù)存到peoplehb里,這樣每個(gè)人拿到大紅包的機(jī)會(huì)就均等了。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace wxhb
class Program
public static int hbNum = 10;//hbNum:紅包數(shù)量
//判斷數(shù)組A中是否存在數(shù)據(jù)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:紅包數(shù)組,保存每個(gè)紅包事先隨機(jī)分配的金額
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個(gè)紅包中隨機(jī)抽一個(gè)紅包,記錄第i個(gè)紅包位置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)); 運(yùn)行第一次分配結(jié)果如下: 預(yù)裝紅包(10個(gè)):6.31 , 2.93 , 2.5 , 6.16 , 9.08 , 5.08 , 1.69 ,17.8 , 0.52 ,47.93 用戶領(lǐng)到的紅包順序:1, 0, 8, 7, 5, 3, 4, 9, 6, 2 用戶領(lǐng)取到的紅包大?。?0個(gè)):2.93, 6.31, 0.52, 17.8, 5.08,6.16, 9.08, 47.93, 1.69, 2.5 運(yùn)行第二次分配結(jié)果如下: 預(yù)裝紅包(10個(gè)):8.89 , 6.25 , 4.96 , 7.16 , 9.05 , 1.49 , 15.01 ,11.08 , 3.98, 32.13 用戶領(lǐng)到的紅包順序:5, 3, 0, 9, 4, 6, 7, 1, 2, 8, 用戶領(lǐng)取到的紅包大?。?0個(gè)):1.49, 7.16, 8.89, 32.13, 9.05,15.01, 11.08, 6.25, 4.96, 3.98 運(yùn)行第三次分配結(jié)果如下: 預(yù)裝紅包(10個(gè)):7.02 , 0.24 , 6.78 , 9.21 , 3.04 , 11.8 , 2.16 ,11.69 , 15.52, 32.55 用戶領(lǐng)到的紅包順序:4, 8, 0, 7, 5, 9, 1, 2, 6, 3, 用戶領(lǐng)取到的紅包大?。?0個(gè)):3.04, 15.52, 7.02, 11.69, 11.8,32.55, 0.24, 6.78, 2.16, 9.21 從運(yùn)行結(jié)果來看,基本符合微信紅包要求,且抽得大紅包的機(jī)會(huì)也均等,與選抽取的先后順序無關(guān)。 1.紅包大小至少為1分。對(duì)應(yīng)的代碼為:if(hb[i] < 0.01)hb[i] = 0.01f; 也就是說,如果紅包金額少于1分,則就要給定1分。 現(xiàn)給定金額為0.10,紅包個(gè)數(shù)為10,運(yùn)行程序分配結(jié)果如下: 預(yù)裝紅包(10個(gè)):0.01 , 0.01 , 0.01 , 0.01 , 0.01 , 0.01 , 0.01 ,0.01 , 0.01 ,0.01 用戶領(lǐng)到的紅包順序:8, 3, 6, 1, 2, 7, 9, 5, 0, 4, 用戶領(lǐng)取到的紅包大?。?0個(gè)):0.01, 0.01, 0.01, 0.01, 0.01,0.01, 0.01, 0.01, 0.01, 0.01 發(fā)現(xiàn)每個(gè)紅包的金額為1分,與實(shí)際情況一致。 2.紅包總金額轉(zhuǎn)化為單位“分”后少于紅包個(gè)數(shù),則沒法正常發(fā)紅包。對(duì)應(yīng)代碼為:if(money <= 0.01){ Console.Write("錢太少,不夠分");return;} 現(xiàn)給定金額為0.05,紅包個(gè)數(shù)為10,運(yùn)行程序結(jié)果如下: 1.代碼可以進(jìn)一步精減。 2.效率可以更一步提高,速度可以更快。 3.尋找更高速、快捷、有效的算法。 [1]安德森ASP NET高級(jí)編程, 清華大學(xué)出版社, 2002 [2] ASP NET程序設(shè)計(jì)基礎(chǔ)與實(shí)訓(xùn)教程,清華大學(xué)出版社,2013 [3]Daniel Cazzulino等C#Web應(yīng)用程序入門經(jīng)典,清華大學(xué)出版社,2003四、運(yùn)行程序進(jìn)行驗(yàn)證
五、非正常情況驗(yàn)證
六、需要改進(jìn)的地方