之前业务中曾经遇到过从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 个的更多相关文章

  1. java程序练习:数组中随机10个数中的最大值

    //定义输入:其实是一个可以保存10个整数的数组 //使用循环遍历,生成10个随机数,放入每个元素中//打桩,数组中的内容 //定义输出变量 //将数组中第一个元素取出,保存在max中,当靶子 //遍 ...

  2. 从N个元素的集合中随机取m个元素的算法实现

    最近有一个需求,比较简单,就是如标题所说的,从N个元素中随机取m个元素,当然这m个元素是不能存在重复的.本以为这么简单的需求,应该有现成的工具类来实现,但是几次查找居然没找到(有知道的可以推荐下哈^_ ...

  3. innerHTML和innerText的区别,以及select元素中怎么取出被选中的option。

    一.innerHTML和innerText的区别. 元素.innerHTML = 字符串,是将一对或一个标签所标识的内容全部替换为所赋予的字符串,如果字符串中有标签,浏览器将自动识别其中的标签. 元素 ...

  4. Oracle如何实现从特定组合中随机读取值

    在这里,我们会用到DBMS_RANDOM包和CASE WHEN语句,思路如下: 一.利用DBMS_RANDOM.RANDOM函数随机生成数值,然后对数值进行取模,如果我们要在10个元素中随机读取的话, ...

  5. java 从List中随机取出一个元素

    java 从List中随机取出一个元素 List<Integer> list = new ArrayList<>(); Random random = new Random() ...

  6. 随机获取一个集合(List, Set)中的元素,随机获取一个Map中的key或value

    利用Java提供的Random类.从List或Set中随机取出一个元素,从Map中随机获取一个key或value. 因为Set没有提供get(int index)方法,仅仅能先获取一个随机数后.利用一 ...

  7. js从数组中随机取出不同的元素

    前言 上午处理个需求需要从一个总数组中随机取出不同的元素.共使用两个方法.第一种方法较常规,经测试有bug,数据量大以后随机几次返回的对象直接是function而不是object. 当然简单数据类型应 ...

  8. python random从集合中随机选择元素

    1.使用python random模块的choice方法随机选择某个元素 from random import choice foo = ['a', 'b', 'c', 'd', 'e'] print ...

  9. js在数组arr中随机获取count数量的元素

    // 在数组arr中随机获取count数量的元素; const getRandomArrayElements = (arr, num) => { // 新建一个数组,将传入的数组复制过来,用于运 ...

随机推荐

  1. 【转】sublime text 3 显示空格和Tab

    因为sublime text3确实太好用了所以也用它写代码了,可是在Python3第一步把preferences.sublime-setting-Default里面的"draw_white_ ...

  2. 入门干货之Grpc的.Net实现-MagicOnion

    此文章简单残暴,学习成本较低,你可以跟着我一起撸代码,一起吐槽,一起砸键盘.以下操作均为 core2.0 环境. 0x01.Grpc 1.介绍  Google主导开发的RPC框架,使用HTTP/2协议 ...

  3. SLAVE为什么一直不动了

    导读 遇到SLAVE延迟很大,binlog apply position一直不动的情况如何排查? 问题描述 收到SLAVE延迟时间一直很大的报警,于是检查一下SLAVE状态(无关状态我给隐去了):   ...

  4. 设计模式六大原则(PHP)

    设计模式的目的是为了更好的代码重用性,可读性,可靠性和可维护性.常用的六大设计模式有:单一职责原则(SRP),里氏替换原则(LSP),依赖倒转原则(DIP),接口隔离原则(ISP),迪米特法则(LOD ...

  5. uboot中 make xxx_config 的作用(以make smdk2410_config为例)

    1.创建到目标板相关文件的链接 ln -s asm-arm asm ln -s arch-s3c24x0 asm-arm/arch ln -s proc-armv asm-arm/proc 2.创建i ...

  6. dotnet core webapi +vue 搭建前后端完全分离web架构

    架构 服务端采用 dotnet core  webapi 前端采用: Vue + router +elementUI+axios 问题 使用前后端完全分离的架构,首先遇到的问题肯定是跨域访问.前后端可 ...

  7. python网站目录扫描器2.0版

    改进了上次乱的要死的. #网站目录扫描器2.0的脚本 import sys import requests import time print('[+]扫描中') def gfc(): f=open( ...

  8. C语言中%d,%p,%u,%lu等都有什么用处

    %d 有符号10进制整数(%ld 长整型,%hd短整型 )%hu 无符号短整形(%u无符号整形,%lu无符号长整形)%i 有符号10进制整数 (%i 和%d 没有区别,%i 是老式写法,都是整型格式) ...

  9. vue vue-style-loader !css-loader错误

    最近在学习vue框架,使用webpack打包vue项目,在执行npm run start的时候 出现如下错误: This dependency was not found: * !!vue-style ...

  10. cesium编程入门(四)界面介绍及小控件隐藏

    感性认识 界面介绍,viewer Geocoder : 查找位置工具,查找到之后会将镜头对准找到的地址,默认使用bing地图 Home Button :视角返回初始位置. Scene Mode Pic ...