需要编写函数实现数组排列,判断重复值,产生1-22随机号码,升序排列
2条回答 默认 最新
- 爱吃芒果的程序猿 2016-12-29 02:45关注
从1-22选5个随机数,这个按照一般逻辑来想,多半是这么一个思路
1. 用new Random().nextInt(22)+1这方方式来生成1-22中的一个随机数
2. 然后把这个随机数加到一个Set中(Set中是帮助去重的)
3. 再判断这个Set大小是否等于5,若等于5则停止,若没有则继续回到步骤1
4. set排序,用TreeSet进行升序排序大体代码如下:
Set<Integer> set = new HashSet<>(); while (set.size() != 5){ int i = random.nextInt(22) + 1; set.add(i); } TreeSet<Integer> treeSet = new TreeSet<>(Integer::compareTo); treeSet.addAll(set); System.out.println(treeSet);
运行结果如下:
若只是完成一个简单功能,以上的代码足够,但是我想介绍和推荐的是下面这种写法,这里要涉及到Java8在Random类中新增的方法ints,
这个方法总的功能就是,从一个范围数字中生成若干个随机数,但是可能重复,所以它的功能和你的描述的问题非常接近,它可以直接实现
从1-22中生成5个随机数,只是,只是它可能有重复而已,下面是ints方法的签名public IntStream ints(long streamSize, int randomNumberOrigin, int randomNumberBound) {
第一个参数就是最终生成随机数的大小,第二个参数是范围的左边边界(包含),第三个参数是范围的右边边界(不包含)
返回值是一个IntStream(对IntStream不熟的话,可以去了解一下Java8的stream,这里你可以理解为一种数据集合结构,类似集合List一样)所以直接这样调用即可完成在1-22中生成5个随机数,但可能有重复
int[] ints = random.ints(5, 1, 23).toArray();
如果你对Java8的stream比较熟悉的话,有重复的东西,可以直接distinct进行去重的
int[] ints = random.ints(5, 1, 23).distinct().toArray();
这样虽然去重了,但是个数就达不到5个了,所以我的思路是这样的:
1. 按照1-22生成5个随机数,并去重,转化为数组A
2. 判断当前数组A大小是否小于5,若大于的话,跳到步骤4,若小于的话,继续按照1-22生成5个随机数,转化为数组B
3. 将数组A和数组B利用stream进行合并,再去重,赋值给数组A,调回步骤2
4. 把当前数组A截取前5个,排序(stream排序很简单)进行返回即可代码如下:
Random random = new Random(); int[] ints = random.ints(5, 1, 23)// 从1-22中生成5个随机数,可能重复 .distinct()// 去重 .toArray();// 转化为数组 // 若当前生成的不重复的随机数还不到5个 while (ints.length < 5){ ints = IntStream.concat(Arrays.stream(ints), random.ints(5, 1, 23))// 再生成5个随机数和之前的生成的随机数合并在一起 .distinct()// 去重 .toArray();// 转化为数组 } // 最后的ints可能会大于5,但是里面的随机数都是不重复 Arrays.stream(ints).limit(5)// 此时直接前面按照5的大小截断即可 .sorted()// 排序,默认升序 .forEach(System.out::println);// 打印
运行结果:
上面的代码虽然看起来稍显复杂,但是由以下两个优点
1. Random.ints生成的随机是均匀分配,而Random.nextInt是正态分布(中间的数几率大,两边的数几率小)
2. HashSet是线程不安全的,IntStream是线程安全的
3. stream的排序更简洁方便,完胜TreeSet
4. 代码风格而言,这个有点因人而异,不过Java8提倡的函数式风格我看起来更好一点,更语义化,哈哈,其实由于每一个链式写法要给你写注释,所以就分段了,其实这个链不长的话,可以不用分段,代码其实更应该像这样,看起来简洁点Random random = new Random(); int[] ints = random.ints(5, 1, 23).distinct().toArray(); while (ints.length < 5){ ints = IntStream.concat(Arrays.stream(ints), random.ints(5, 1, 23)).distinct().toArray(); } Arrays.stream(ints).limit(5).sorted().forEach(System.out::println);
以上是我的想法,欢迎讨论指正
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 2无用
悬赏问题
- ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
- ¥15 如何在scanpy上做差异基因和通路富集?
- ¥20 关于#硬件工程#的问题,请各位专家解答!
- ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
- ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
- ¥30 截图中的mathematics程序转换成matlab
- ¥15 动力学代码报错,维度不匹配
- ¥15 Power query添加列问题
- ¥50 Kubernetes&Fission&Eleasticsearch
- ¥15 報錯:Person is not mapped,如何解決?