微信怎么抢红包(微信红包封面领取序列号)

[摘要]引言春节不可或缺的活动就是抢红包。从以前的纸质红包到现在的互联网红包(以微信红包为首),今天我们就来分析一下抢红包的算法,其中有一些是微信红包。看完它们

[摘要]引言春节不可或缺的活动就是抢红包。从以前的纸质红包到现在的互联网红包(以微信红包为首),今天我们就来分析一下抢红包的算法,其中有一些是微信红包。看完它们,你会知道最好的运气是怎么来的!

算法一:剩余量随机法不推荐算法一。算法1的全称是剩余量随机法。听名字就知道这种方法是随机分配剩余金额。我们先来看代码。

前言

春节不可或缺的活动就是抢红包。从以前的纸质红包到现在的互联网红包(以微信红包为首),今天我们就来分析一下抢红包的算法,其中有一些是微信红包。看完它们,你会知道最好的运气是怎么来的!

微信怎么抢红包(微信红包封面领取序列号)插图

算法一:剩余金额随机法

第一,算法不推荐。算法的全称是剩余量随机法。看名字就知道这种方法是随机分配剩余金额。我们先来看代码。

// 分配红包的算法private static void testPocket(BigDecimal amount, BigDecimal min, BigDecimal num) {BigDecimal remain = amount.subtract(min.multiply(num));final Random random = new Random();final BigDecimal hundred = new BigDecimal("100");BigDecimal sum = BigDecimal.ZERO;BigDecimal redpeck ;for (int i = 0; i < num.intValue(); i++) { final int nextInt = random.nextInt(100); if (i == num.intValue() - 1) { redpeck = remain; } else { redpeck = new BigDecimal(nextInt).multiply(remain).divide(hundred, 2, RoundingMode.FLOOR); } if (remain.compareTo(redpeck) > 0) { remain = remain.subtract(redpeck); } else { remain = BigDecimal.ZERO; } sum = sum.add(min.add(redpeck)); System.out.println("第" + (i + 1) + "个人抢到红包金额为:" + min.add(redpeck).setScale(2, BigDecimal.ROUND_HALF_UP));}System.out.println("红包总额:" + sum.setScale(2, BigDecimal.ROUND_HALF_UP));}// 测试代码public static void main(String[] args) { BigDecimal amount = new BigDecimal(100).setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal min = new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal num = new BigDecimal(10).setScale(2, BigDecimal.ROUND_HALF_UP); testPocket2(amount,min,num);}

微信怎么抢红包(微信红包封面领取序列号)插图(1)//分发红包私有静态void测试口袋的算法(bigdecimal amount,bigdecimal min,bigdecimal num){ bigdecimal remain = amount . subtract(min . multiple(num));最终Random Random = new Random();最终BigDecimal百=新BigDecimal(& # 34;100");BigDecimal sum = BigDecimal。零;BigDecimal redpeckfor(int I = 0;我& ltnum . int value();i++){ final int nextInt = random . nextInt(100);if(I = = num . int value()-1){ red peck = remain;} else { red peck = new BigDecimal(nextInt)。乘法(保持)。除(百,2,舍入模式。楼层);} if(remain . compare to(red peck)& gt;0){ remain = remain . subtract(red peck);} else { remain = BigDecimal。零;} sum = sum . add(min . add(red peck));system . out . println(& # 34;& # 34;+(I+1)+& # 34;个人抢到的红包金额是:& # 34;+ min.add(redpeck)。setScale(2,BigDecimal。ROUND _ HALF _ UP));} system . out . println(& # 34;红包总金额:& # 34;+ sum.setScale(2,BigDecimal。ROUND _ HALF _ UP));}//测试代码公共静态void main(string[]args){ bigdecimal amount = newbigdecimal(100)。setscale (2,bigdecimal . round _ half _ up);BigDecimal min =新的BigDecimal(0.01)。setScale(2,BigDecimal。ROUND _ HALF _ UP);BigDecimal num = new BigDecimal(10)。setScale(2,BigDecimal。ROUND _ HALF _ UP);testPocket2(amount,min,num);}

我们可以看到,这种方法有明显的缺陷,就是一开始收到红包的人可能得到的金额最大,后来收到的金额会逐渐变小,因为他是从剩余金额中随机抽取的。显然,微信肯定不会用这种方式作为红包划分算法。不然每次有红包,都有可能马上得到最好的运气,但显然不是。

算法二:整体随机法

整额随机法的公式:红包总额*随机数/随机数之和。这个方法的核心是用一个随机数作为划分红包的标准。这个随机数是通过random类随机生成的。他的随机性比较大,看起来和我们平时抢红包的方式差不多,但是微信红包不采用这种方式,因为这种随机性太大,不公平。

private static void testPocket2(BigDecimal amount,BigDecimal min ,BigDecimal num){ final Random random = new Random(); final int[] rand = new int[num.intValue()]; BigDecimal sum1 = BigDecimal.ZERO; BigDecimal redpeck ; int sum = 0; for (int i = 0; i < num.intValue(); i++) { rand[i] = random.nextInt(100); sum += rand[i]; } final BigDecimal bigDecimal = new BigDecimal(sum); BigDecimal remain = amount.subtract(min.multiply(num)); for (int i = 0; i < rand.length; i++) { if(i == num.intValue() -1){ redpeck = remain; }else{ redpeck = remain.multiply(new BigDecimal(rand[i])).divide(bigDecimal,2,RoundingMode.FLOOR); } if(remain.compareTo(redpeck) > 0){ remain = remain.subtract(redpeck); }else{ remain = BigDecimal.ZERO; } sum1= sum1.add(min.add(redpeck)).setScale(2, BigDecimal.ROUND_HALF_UP); System.out.println("第"+(i+1)+"个人抢到红包金额为:"+min.add(redpeck).setScale(2, BigDecimal.ROUND_HALF_UP)); } System.out.println("红包总额:"+sum1);}// 测试代码public static void main(String[] args) { BigDecimal amount = new BigDecimal(100).setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal min = new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal num = new BigDecimal(10).setScale(2, BigDecimal.ROUND_HALF_UP); testPocket2(amount,min,num);}

微信怎么抢红包(微信红包封面领取序列号)插图(2)private static void test pocket 2(BigDecimal amount,BigDecimal min,BigDecimal num){ final Random Random = new Random();final int[]rand = new int[num . int value()];BigDecimal sum1 = BigDecimal。零;BigDecimal redpeckint sum = 0;for(int I = 0;我& ltnum . int value();i++){ rand[I]= random . nextint(100);sum+= rand[I];} final BigDecimal BigDecimal = new BigDecimal(sum);BigDecimal remain = amount . subtract(min . multiply(num));for(int I = 0;我& lt兰德.长度;i++){ if(I = = num . int value()-1){ red peck = remain;} else { red peck = remain . multiply(new BigDecimal(rand[I]))。divide(bigDecimal,2,RoundingMode。楼层);} if(remain . compare to(red peck)& gt;0){ remain = remain . subtract(red peck);}else{ remain = BigDecimal。零;} sum1= sum1.add(min.add(redpeck))。setScale(2,BigDecimal。ROUND _ HALF _ UP);system . out . println(& # 34;& # 34;+(I+1)+& # 34;个人抢到的红包金额是:& # 34;+min.add(redpeck)。setScale(2,BigDecimal。ROUND _ HALF _ UP));} system . out . println(& # 34;红包总金额:& # 34;+sum 1);}//测试代码公共静态void main(string[]args){ bigdecimal amount = newbigdecimal(100)。setscale (2,bigdecimal . round _ half _ up);BigDecimal min =新的BigDecimal(0.01)。setScale(2,BigDecimal。ROUND _ HALF _ UP);BigDecimal num = new BigDecimal(10)。setScale(2,BigDecimal。ROUND _ HALF _ UP);testPocket2(amount,min,num);}

他的随机性很高,不是最佳选择。

算法三:割线法

割线法是指把红包的总金额想象成一条长线段,每个人抢到的金额就是这条主线段分割出来的若干子线段。当所有切割点都确定后,子线段的长度也就确定了。这样大家来抢红包的时候,只需要领取与子段长度相等的红包金额即可。

微信怎么抢红包(微信红包封面领取序列号)插图(3)

private static void testPocket3(BigDecimal amount, BigDecimal min, BigDecimal num) { final Random random = new Random(); final int[] rand = new int[num.intValue()]; BigDecimal sum1 = BigDecimal.ZERO; BigDecimal redpeck; int sum = 0; for (int i = 0; i < num.intValue(); i++) { rand[i] = random.nextInt(100); sum += rand[i]; } final BigDecimal bigDecimal = new BigDecimal(sum); BigDecimal remain = amount.subtract(min.multiply(num)); for (int i = 0; i < rand.length; i++) { if (i == num.intValue() - 1) { redpeck = remain; } else { redpeck = remain.multiply(new BigDecimal(rand[i])) .divide(bigDecimal, 2, RoundingMode.FLOOR); } if (remain.compareTo(redpeck) > 0) { remain = remain.subtract(redpeck).setScale(2, BigDecimal.ROUND_HALF_UP); } else { remain = BigDecimal.ZERO; } sum1 = sum1.add(min.add(redpeck).setScale(2, BigDecimal.ROUND_HALF_UP)); System.out.println("第" + (i + 1) + "个人抢到红包金额为:" + min.add(redpeck)); } System.out.println("红包总额:" + sum1);}// 测试代码public static void main(String[] args) { BigDecimal amount = new BigDecimal(100).setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal min = new BigDecimal(0.01).setScale(2, BigDecimal.ROUND_HALF_UP); BigDecimal num = new BigDecimal(10).setScale(2, BigDecimal.ROUND_HALF_UP); testPocket2(amount,min,num);}

微信怎么抢红包(微信红包封面领取序列号)插图(4)private static void test pocket 3(BigDecimal amount,BigDecimal min,BigDecimal num){ final Random Random = new Random();final int[]rand = new int[num . int value()];BigDecimal sum1 = BigDecimal。零;BigDecimal redpeckint sum = 0;for(int I = 0;我& ltnum . int value();i++){ rand[I]= random . nextint(100);sum+= rand[I];} final BigDecimal BigDecimal = new BigDecimal(sum);BigDecimal remain = amount . subtract(min . multiply(num));for(int I = 0;我& lt兰德.长度;i++){ if(I = = num . int value()-1){ red peck = remain;} else { red peck = remain . multiply(new BigDecimal(rand[I]))。divide(bigDecimal,2,RoundingMode。楼层);} if(remain . compare to(red peck)& gt;0){ remain = remain . subtract(red peck)。setScale(2,BigDecimal。ROUND _ HALF _ UP);} else { remain = BigDecimal。零;} sum1 = sum1.add(min.add(redpeck))。setScale(2,BigDecimal。ROUND _ HALF _ UP));system . out . println(& # 34;& # 34;+(I+1)+& # 34;个人抢到的红包金额是:& # 34;+min . add(red peck));} system . out . println(& # 34;红包总金额:& # 34;+sum 1);}//测试代码公共静态void main(string[]args){ bigdecimal amount = newbigdecimal(100)。setscale (2,bigdecimal . round _ half _ up);BigDecimal min =新的BigDecimal(0.01)。setScale(2,BigDecimal。ROUND _ HALF _ UP);BigDecimal num = new BigDecimal(10)。setScale(2,BigDecimal。ROUND _ HALF _ UP);testPocket2(amount,min,num);}

他的随机性也比较大,但是他最致命的还是性能,因为他需要进行切割这一步。

算法四:二倍均值法

第四种算法是微信红包目前使用的算法(大致思路,代码模拟),双倍平均的公式是2 *剩余金额/剩余红包数。

BigDecimal remain = amount.subtract(min.multiply(num)); final Random random = new Random(); final BigDecimal hundred = new BigDecimal("100"); final BigDecimal two = new BigDecimal("2"); BigDecimal sum = BigDecimal.ZERO; BigDecimal redpeck; for (int i = 0; i < num.intValue(); i++) { final int nextInt = random.nextInt(100); if(i == num.intValue() -1){ redpeck = remain; }else{ redpeck = new BigDecimal(nextInt).multiply(remain.multiply(two).divide(num.subtract(new BigDecimal(i)),2,RoundingMode.CEILING)).divide(hundred,2, RoundingMode.FLOOR); } if(remain.compareTo(redpeck) > 0){ remain = remain.subtract(redpeck).setScale(2, BigDecimal.ROUND_HALF_UP); }else{ remain = BigDecimal.ZERO; } sum = sum.add(min.add(redpeck)).setScale(2, BigDecimal.ROUND_HALF_UP); System.out.println("第"+(i+1)+"个人抢到红包金额为:"+min.add(redpeck)); } System.out.println("红包总额:" + sum);}

微信怎么抢红包(微信红包封面领取序列号)插图(5)BigDecimal remain = amount . subtract(min . multiply(num));最终Random Random = new Random();最终BigDecimal百=新BigDecimal(& # 34;100");final BigDecimal two = new BigDecimal(& # 34;2");BigDecimal sum = BigDecimal。零;BigDecimal redpeckfor(int I = 0;我& ltnum . int value();i++){ final int nextInt = random . nextInt(100);if(I = = num . int value()-1){ red peck = remain;} else { red peck = new BigDecimal(nextInt)。乘(保持。乘(二)。divide(num . subtract(new BigDecimal(I)),2,RoundingMode。天花板))。除(百,2,舍入模式。楼层);} if(remain . compare to(red peck)& gt;0){ remain = remain . subtract(red peck)。setScale(2,BigDecimal。ROUND _ HALF _ UP);}else{ remain = BigDecimal。零;} sum = sum.add(min.add(redpeck))。setScale(2,BigDecimal。ROUND _ HALF _ UP);system . out . println(& # 34;& # 34;+(I+1)+& # 34;个人抢到的红包金额是:& # 34;+min . add(red peck));} system . out . println(& # 34;红包总金额:& # 34;+sum);}

他还是保证了每个红包的金额大致相等,不会出现极端的情况。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/201767.html

发表回复

登录后才能评论