本帖最后由 灰椋之夜 于 2019-6-26 15:56 编辑
这个技术帖可以理解为是个纯粹的萌新发现新大陆的感受,在这里要感谢室友陈总提供的部分技术支持。 在前两天上课学习到方法,数组和随机的时候有一道课后题是彩票抽奖。虽然本人最大的毛病就是看到题了就写,以至于很多时候都是题看一半然后脑补另一半,结果就是最后写出来的东西不是人家问的东西然后仰天长叫,啊~~~。 这道题的本质就是简单随机不重复抽样的一种实现。(以下内容供同为萌新参考,大佬看看然后嘲笑一下就好。)下面上题:
一个大V直播抽奖,奖品是现金红包,分别有{2,588,888,1000,10000}五个奖金。请使用代码模拟抽奖,打印出每个奖项,奖项的出现顺序要随机且不重复。打印效果如下:(随机顺序,不一定是下面的顺序) 888元的奖金被抽出 588元的奖金被抽出 10000元的奖金被抽出 1000元的奖金被抽出 2元的奖金被抽出
这道题的本质就是将上面数组内的五个数字随机不重复全部排列一下就ok了。 其他的东西我们就不在本文中考虑,我们只分享一下关于这个随机不重复排列。在这里分享一下两种思考方式: 下面代码的前提统一为: int[] arr = {2,588, 888, 1000, 10000};
第一种,也就是和参考答案差不多的方式,先上代码: [Java] 纯文本查看 复制代码 for (int i = 0; i < brr.length; i++) {
int j = r.nextInt(brr.length);
if (!exist(brr,arr[j])){
brr[i]=[/i]arr[j];
}else{
i--;
}
} 这一部分的整体思想就是创建一个新的数组,这个新的数组是由原数组的索引随机不重复构成然后映射到原数组。也就是int[] brr = newint[5];。这里面有个exist的方法(exist(int[] arr,int b)),其本质是判断b是否在数组arr中存在。关于为什么不直接把原数组直接排序,是因为萌新们的随机数获取是来自于连续的一个从0开始的整数范围,而这个范围的取值恰巧和数组的索引的取值相同,所以直接就选用这个来映射原数组。
第二种,这个方法的思路来自于我的室友,陈总。先感谢一下,啪啪啪。 再来一串代码: [Java] 纯文本查看 复制代码 for(int i = arr.length; i > 0; i--){
int num = random.nextInt(i);
System.out.println(arr[num] + “元的现金被抽到”);
for(int j = num; j < i-1; j++){
arr[j] = arr[j + 1];
}
} 这一部分的整体构思,就和数学例题中抽乒乓球的感觉是一样的,只不过因为数组长度固定所以我们每次抽的时候就相当于加了个隔板,(然后为了不影响原数组,我们新建了一个数组,并且把原数组的元素逐个赋值过去。)把抽到过的东西排除,剩下的挪到隔板里,然后在隔板里面再抽,其中我们在把随机抽的范围也随着变小,直到都放进隔板里没有东西为止。
这个里面就不需要在进行重复判断,因为剩下来的必定是没有参与过输出的数。
我们不针对两个方法哪个好那个不好做任何评价,(实际上是因为没什么评判标准)在这里实际上是想说,不论是做题也好,现实生活中做什么事都好,都没有一种固定的方式,你可以找到任何一种符合你自己做事方法的方式,不论是整体去对应,还是逐一排除,没有好与不好,只有适不适合自己,最终只要能完成自己的目标就是最好的方法。 最后再次感谢陈总提供的解题思路启发。 |