内容简介:支付宝扫福背后的可能涉及的一个问题,就是五福已经花花卡怎么得到。这里面涉及到很多的游戏规则,当然问题的本质就是从一个数组中按照一定的比例获取一项元素。随机获取一个指定数组的元素和按照一定比例获取随机项这种功能在一定的在日常开发中肯定很常见。前者相对实现起来比较简单,但是后者网上有千奇百怪的而实现方式,而且其代码俩都相对较大,领人阅读的时候不能很愉快。当然每个人都有每个人的实现方式,凡是自己实现确实是不错的选择,至少是对自己的一种锻炼。今天我就给出我的一种实现方式相对其他方式极大的简化了原理和实现方式。另外其
支付宝扫福背后的可能涉及的一个问题,就是五福已经花花卡怎么得到。这里面涉及到很多的游戏规则,当然问题的本质就是从一个数组中按照一定的比例获取一项元素。
随机获取一个指定数组的元素和按照一定比例获取随机项这种功能在一定的在日常开发中肯定很常见。前者相对实现起来比较简单,但是后者网上有千奇百怪的而实现方式,而且其代码俩都相对较大,领人阅读的时候不能很愉快。当然每个人都有每个人的实现方式,凡是自己实现确实是不错的选择,至少是对自己的一种锻炼。今天我就给出我的一种实现方式相对其他方式极大的简化了原理和实现方式。另外其实按照现有的常见系统这里面处理涉看似简单的游戏规则外,还有很多的AI和大数据成品,影响着随机的结果。具体代码见github
此处有彩蛋
元宵节前留言解密内容有机会获得现金红包
AUAAKCjTM0M7G1L+WSB80R5Iiv6zLcnXz8OESQJGbzktlFj0M5n0p6Q4gOO6r6Pr5AGWIYbMwm//IMqQ/KTLEFl8EQ
实现方式
1 /** 2 * 生成制定范围内的随机数 3 * 4 * @param scopeMin 5 * @param scoeMax 6 * @return 7 */ 8 public static int integer(int scopeMin, int scoeMax) { 9 Random random = new Random(); 10 return (random.nextInt(scoeMax) % (scoeMax - scopeMin + 1) + scopeMin); 11 } 12 /** 13 * 从指定的数组中随机数组中的某个元素 14 */ 15 public static <T> T randomItem(T[] param) { 16 int index = integer(0, param.length); 17 return param[index]; 18 }
测试
1 @Test 2 public void testRandomItem(){ 3 for (int j = 0; j < 10; j++) { 4 Map<Integer,Integer> map = new HashMap(); 5 for (int i = 0; i < 1000000; i++) { 6 Integer integer = RandomUtil.randomItem(new Integer[]{10, 30, 50}); 7 if(map.containsKey(integer)){ 8 map.put(integer,map.get(integer)+1); 9 }else{ 10 map.put(integer,1); 11 } 12 } 13 int count = map.get(10)+map.get(30)+map.get(50); 14 String str = "10/30/50 ="+map.get(10)+":"+map.get(30)+":"+map.get(50) 15 +"("+count+")"; 16 System.out.println(str); 17 } 18 }
测试结果
此处我随机了1000000次,下面是一些测试结果,从结果上来看相对还是比较靠谱
110/30/50 =333651:332493:333856(1000000) 210/30/50 =333098:333090:333812(1000000) 310/30/50 =333791:332406:333803(1000000) 410/30/50 =333052:333188:333760(1000000) 510/30/50 =333131:333132:333737(1000000) 610/30/50 =333920:333441:332639(1000000) 710/30/50 =332876:333978:333146(1000000) 810/30/50 =333948:332682:333370(1000000) 910/30/50 =333180:333794:333026(1000000) 1010/30/50 =333030:333798:333172(1000000)
按照比例随机项
相对网络上的其他方式,此方法的实现原理很简单就随机一个数字,通过这个数字反映出其位置,然后通过位置即可保证随机比例,测试的时候发现随机的次数越多比例越接近设定的值。
实现
1 /** 2 * 从指定的数组中按照指定比例返回指定的随机元素 3 * 4 * @param param 随机数组 5 * @param percentum 比例 6 * @param <T> 7 * @return 8 */ 9 public static <T> T randomItem(T[] param, double[] percentum) { 10 int length = percentum.length; 11 Integer[] ints = ArrayUtil.doubleBitCount(percentum); 12 int max = Collections.max(Arrays.asList(ints)); 13 int[] arr = new int[length]; 14 int sum = 0; 15 Map map = new HashMap(length); 16 StringBuffer buffer = new StringBuffer(); 17 for (int i = 0; i < max; i++) { 18 buffer.append("0"); 19 } 20 int multiple = Integer.parseInt("1" + buffer.toString()); 21 for (int i = 0; i < length; i++) { 22 int temp = (int) (percentum[i] * multiple); 23 arr[i] = temp; 24 if (i == 0) { 25 map.put(i, new int[]{1, temp}); 26 } else { 27 map.put(i, new int[]{sum, sum + temp}); 28 } 29 sum += temp; 30 } 31 int indexSum = integer(1, sum); 32 int index = -1; 33 for (int i = 0; i < length; i++) { 34 int[] scope = (int[]) map.get(i); 35 if (indexSum == 1) { 36 index = 0; 37 break; 38 } 39 if (indexSum > scope[0] && indexSum <= scope[1]) { 40 index = i; 41 break; 42 } 43 } 44 if (index == -1) { 45 throw new RuntimeException("随机失败"); 46 } else { 47 return param[index]; 48 } 49 }
测试
1 @Test 2 public void testRandomItemRatio(){ 3 4 for (int j = 0; j < 10; j++) { 5 Map<Integer,Integer> map = new HashMap(); 6 for (int i = 0; i < 1000000; i++) { 7 double[] percentum = new double[]{0.6,0.3,0.1}; 8 Integer integer = RandomUtil.randomItem(new Integer[]{10, 30, 50}, percentum); 9 if(map.containsKey(integer)){ 10 map.put(integer,map.get(integer)+1); 11 }else{ 12 map.put(integer,1); 13 } 14 } 15 int count = map.get(10)+map.get(30)+map.get(50); 16 String str = "10/30/50 ="+map.get(10)+":"+map.get(30)+":"+map.get(50) 17 +"("+count+") ->"+ 18 StringHelper.formatNumber(new BigDecimal(map.get(10)/(float)count),"#.0000")+":"+ 19 StringHelper.formatNumber(new BigDecimal(map.get(30)/(float)count),"#.0000")+":"+ 20 StringHelper.formatNumber(new BigDecimal(map.get(50)/(float)count),"#.0000"); 21 System.out.println(str); 22 } 23 24 // 25 System.out.println("测试万分之一的概率"); 26 for (int j = 0; j < 10; j++) { 27 Map<Integer,Integer> map2 = new HashMap(); 28 for (int i = 0; i < 1000000; i++) { 29 double[] percentum = new double[]{0.6,0.4999,0.0001}; 30 Integer integer = RandomUtil.randomItem(new Integer[]{10, 30, 50}, percentum); 31 if(map2.containsKey(integer)){ 32 map2.put(integer,map2.get(integer)+1); 33 }else{ 34 map2.put(integer,1); 35 } 36 } 37 int count = map2.get(10)+map2.get(30)+map2.get(50); 38 String str = "10/30/50 ="+map2.get(10)+":"+map2.get(30)+":"+map2.get(50) 39 +"("+count+") ->"+ 40 StringHelper.formatNumber(new BigDecimal(map2.get(10)/(float)count),"#.00000")+":"+ 41 StringHelper.formatNumber(new BigDecimal(map2.get(30)/(float)count),"#.00000")+":"+ 42 StringHelper.formatNumber(new BigDecimal(map2.get(50)/(float)count),"#.00000"); 43 System.out.println(str); 44 } 45 System.out.println("测试十万分之一的概率"); 46 for (int j = 0; j < 10; j++) { 47 Map<Integer,Integer> map3 = new HashMap(); 48 for (int i = 0; i < 1000000; i++) { 49 double[] percentum = new double[]{0.6,0.49999,0.00001}; 50 Integer integer = RandomUtil.randomItem(new Integer[]{10, 30, 50}, percentum); 51 if(map3.containsKey(integer)){ 52 map3.put(integer,map3.get(integer)+1); 53 }else{ 54 map3.put(integer,1); 55 } 56 } 57 int count = map3.get(10)+map3.get(30)+map3.get(50); 58 String str = "10/30/50 ="+map3.get(10)+":"+map3.get(30)+":"+map3.get(50) 59 +"("+count+") ->"+ 60 StringHelper.formatNumber(new BigDecimal(map3.get(10)/(float)count),"#.000000")+":"+ 61 StringHelper.formatNumber(new BigDecimal(map3.get(30)/(float)count),"#.000000")+":"+ 62 StringHelper.formatNumber(new BigDecimal(map3.get(50)/(float)count),"#.000000"); 63 System.out.println(str); 64 } 65 }
测试结果
110/30/50 =600354:299397:100249(1000000) ->0.6004:0.2994:0.1002 210/30/50 =600025:299830:100145(1000000) ->0.6000:0.2998:0.1001 310/30/50 =600126:299818:100056(1000000) ->0.6001:0.2998:0.1001 410/30/50 =600687:299354:99959(1000000) ->0.6007:0.2994:0.1000 510/30/50 =600916:299568:99516(1000000) ->0.6009:0.2996:0.0995 610/30/50 =599388:300589:100023(1000000) ->0.5994:0.3006:0.1000 710/30/50 =599777:299881:100342(1000000) ->0.5998:0.2999:0.1003 810/30/50 =599734:300583:99683(1000000) ->0.5997:0.3006:0.0997 910/30/50 =599214:300557:100229(1000000) ->0.5992:0.3006:0.1002 1010/30/50 =600500:299443:100057(1000000) ->0.6005:0.2994:0.1001 11测试万分之一的概率 1210/30/50 =545096:454801:103(1000000) ->0.54510:0.45480:0.00010 1310/30/50 =545798:454116:86(1000000) ->0.54580:0.45412:0.00009 1410/30/50 =545413:454495:92(1000000) ->0.54541:0.45450:0.00009 1510/30/50 =545842:454068:90(1000000) ->0.54584:0.45407:0.00009 1610/30/50 =544981:454932:87(1000000) ->0.54498:0.45493:0.00009 1710/30/50 =545930:453973:97(1000000) ->0.54593:0.45397:0.00010 1810/30/50 =545555:454358:87(1000000) ->0.54555:0.45436:0.00009 1910/30/50 =546784:453122:94(1000000) ->0.54678:0.45312:0.00009 2010/30/50 =545536:454370:94(1000000) ->0.54554:0.45437:0.00009 2110/30/50 =545724:454168:108(1000000) ->0.54572:0.45417:0.00011 22测试十万分之一的概率 2310/30/50 =545508:454484:8(1000000) ->0.545508:0.454484:0.000008 2410/30/50 =545711:454281:8(1000000) ->0.545711:0.454281:0.000008 2510/30/50 =545483:454506:11(1000000) ->0.545483:0.454506:0.000011 2610/30/50 =545286:454706:8(1000000) ->0.545286:0.454706:0.000008 2710/30/50 =545381:454612:7(1000000) ->0.545381:0.454612:0.000007 2810/30/50 =545623:454368:9(1000000) ->0.545623:0.454368:0.000009 2910/30/50 =546073:453914:13(1000000) ->0.546073:0.453914:0.000013 3010/30/50 =545580:454403:17(1000000) ->0.545580:0.454403:0.000017 3110/30/50 =545413:454582:5(1000000) ->0.545413:0.454582:0.000005 3210/30/50 =545211:454781:8(1000000) ->0.545211:0.454781:0.000008
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 解读目的地预测背后的AI算法
- 微软开源了 Bing 搜索背后的关键算法
- MySQL索引背后的数据结构及算法原理
- 搜索引擎背后的经典数据结构和算法
- MySQL索引背后的数据结构及算法原理
- IT运维平台算法背后的两大“神助攻”
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
人类2.0
皮埃罗∙斯加鲁菲(Piero Scaruffi) / 闫景立、牛金霞 / 中信出版集团股份有限公司 / 2017-2-1 / CNY 68.00
《人类2.0:在硅谷探索科技未来》从在众多新技术中选择了他认为最有潜力塑造科技乃至人类未来的新技术进行详述,其中涉及大数据、物联网、人工智能、纳米科技、虚拟现实、生物技术、社交媒体、区块链、太空探索和3D打印。皮埃罗用一名硅谷工程师的严谨和一名历史文化学者的哲学视角,不仅在书中勾勒出这些新技术的未来演变方向和面貌,还对它们对社会和人性的影响进行了深入思考。 为了补充和佐证其观点,《人类2.0......一起来看看 《人类2.0》 这本书的介绍吧!