[JAVA] - 从 m 个元素中随机选中 n 个
之前业务中曾经遇到过从m个元素中选取 n 个的需求,当时只是跑循环根据长度进行随机选取,然后放入 Set 中去重,一直到收集到足够的个数。
这样做的缺点很明显,当剩下的元素个数越少的时候,选取的元素越容易重复,并且,使用 Set 去重,值相同的字符串会被认为是相同的元素,即使给入的数组确实有重复的数据。
直到最近看到了 Fisher-Yates 洗牌算法,从中收到启发,写了一个从 m 个元素中选取 n 个的方法,该方法性能上有了很大提升,并且可以保证取到的元素的索引绝对不会重复。如果数组中的确有相同的元素,也不会影响到被选取的概率。
public static <T> T[] randomSelected(T[] array, int num) {
T[] temp = Arrays.copyOf(array, array.length);// 获得一个该数组的复制
int length = temp.length;
int left = length;
while (length - left < num) {// length - left 为还需要计算多少次
int i = (int) Math.floor(Math.random() * left--);// 随机选取一个元素,left 自减,这样不会覆盖上次产生的结果,并将下次选取的范围缩小
T tmp = temp[i];// 将被选中的数与数组的最后一位进行调换
temp[i] = temp[left];
temp[left] = tmp;
}
return Arrays.copyOfRange(temp, 0, num > length ? length : num);// 从临时数组中复制出指定长度的数组
}
该算法不仅速度快,而且索引绝对不会重复!(如果数组里面有重复的元素,我认为这是你想要的结果,毕竟去重不是一件难事) 如果 传入的 num 等于数组的长度,还可以得到一个被打乱了顺序的数组!
[JAVA] - 从 m 个元素中随机选中 n 个的更多相关文章
- java程序练习:数组中随机10个数中的最大值
//定义输入:其实是一个可以保存10个整数的数组 //使用循环遍历,生成10个随机数,放入每个元素中//打桩,数组中的内容 //定义输出变量 //将数组中第一个元素取出,保存在max中,当靶子 //遍 ...
- 从N个元素的集合中随机取m个元素的算法实现
最近有一个需求,比较简单,就是如标题所说的,从N个元素中随机取m个元素,当然这m个元素是不能存在重复的.本以为这么简单的需求,应该有现成的工具类来实现,但是几次查找居然没找到(有知道的可以推荐下哈^_ ...
- innerHTML和innerText的区别,以及select元素中怎么取出被选中的option。
一.innerHTML和innerText的区别. 元素.innerHTML = 字符串,是将一对或一个标签所标识的内容全部替换为所赋予的字符串,如果字符串中有标签,浏览器将自动识别其中的标签. 元素 ...
- Oracle如何实现从特定组合中随机读取值
在这里,我们会用到DBMS_RANDOM包和CASE WHEN语句,思路如下: 一.利用DBMS_RANDOM.RANDOM函数随机生成数值,然后对数值进行取模,如果我们要在10个元素中随机读取的话, ...
- java 从List中随机取出一个元素
java 从List中随机取出一个元素 List<Integer> list = new ArrayList<>(); Random random = new Random() ...
- 随机获取一个集合(List, Set)中的元素,随机获取一个Map中的key或value
利用Java提供的Random类.从List或Set中随机取出一个元素,从Map中随机获取一个key或value. 因为Set没有提供get(int index)方法,仅仅能先获取一个随机数后.利用一 ...
- js从数组中随机取出不同的元素
前言 上午处理个需求需要从一个总数组中随机取出不同的元素.共使用两个方法.第一种方法较常规,经测试有bug,数据量大以后随机几次返回的对象直接是function而不是object. 当然简单数据类型应 ...
- python random从集合中随机选择元素
1.使用python random模块的choice方法随机选择某个元素 from random import choice foo = ['a', 'b', 'c', 'd', 'e'] print ...
- js在数组arr中随机获取count数量的元素
// 在数组arr中随机获取count数量的元素; const getRandomArrayElements = (arr, num) => { // 新建一个数组,将传入的数组复制过来,用于运 ...
随机推荐
- JSP中的“小饼干”Cookie,用来存储数组的方式(下方已String类型的数组为例:)
1.Cookie常用方法中,存储数据的方式: Cookie cookie = new Cookie("key","Value"); response.addCo ...
- XCode v9.6.2017.0830
新生命团队基础框架X组件,包括网络.数据库.安全.多线程.反射.序列化.模版引擎.服务代理.远程过程调用等模块,包括Mvc后台魔方.超级码神工具.消息队列等子系统,支持Mono/Android/iOS ...
- php中的echo,json_decode,json_encode常用函数使用注意事项
---恢复内容开始--- 1.echo函数 echo只能输出单个字符串或者整数,不能直接输出数组.要输出多个字符串必须用分号 eg: echo可以输出字符串加变量,如果输出的数字字符串则会将对应的数字 ...
- async/await 执行顺序详解
随着async/await正式纳入ES7标准,越来越多的人开始研究据说是异步编程终级解决方案的 async/await.但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 ...
- c#中常用集合类和集合接口之集合类系列【转】
常用集合接口系列:http://www.cnblogs.com/fengxiaojiu/p/7997704.html 常用集合类系列:http://www.cnblogs.com/fengxiaoji ...
- Java反射-高级知识掌握
PS:本文就Java反射的高级知识做下汇总,理清在什么情况下,我们应该去使用反射,提供框架的健壮性,ps:xieyang@163.com/xieyang@163.com
- Generator函数语法解析
转载请注明出处: Generator函数语法解析 Generator函数是ES6提供的一种异步编程解决方案,语法与传统函数完全不同.以下会介绍一下Generator函数. 写下这篇文章的目的其实很简单 ...
- 【CSS3 transform属性和过渡属性详解】
CSS3transform属性详解 transform字面上就是变形,改变的意思. 在CSS3中transform主要包括以下几种:旋转rotate.扭曲skew.缩放scale和移动translat ...
- 最长递减子序列(nlogn)(个人模版)
最长递减子序列(nlogn): int find(int n,int key) { ; int right=n; while(left<=right) { ; if(res[mid]>ke ...
- [51nod1357]密码锁
有一个密码锁,其有N位,每一位可以是一个0~9的数字,开启密码锁需要将锁上每一位数字转到解锁密码一致.这个类似你旅行用的行李箱上的密码锁,密码锁的每一位其实是一个圆形转盘,上面依次标了0,1,...9 ...