一个数组通过配置随机抽取组成小数组
发布于: 2021 年 03 月 31 日
1.场景
现有一个数组,想抽出其中一部分元素组成另外一个小一点的数组,又不希望完全随机抽出,比如希望原数组的前 20%抽多点,中间的 50%少抽点,最后的 30%再多抽点,而且希望在范围内是不重复随机抽取
2.思路将不同的配置,转化成固定要取的数量的区域,再从不同的区域里使用不重复随机算法取
3.Java Code
package kowalski;
import java.util.ArrayList;import java.util.Collections;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Random;import java.util.concurrent.ThreadLocalRandom;
/** * Created by kowalski.zhang on 2018/6/6 */public final class PickUtil {
  private static Random random = ThreadLocalRandom.current();
  private PickUtil() {  }
  /***   * just pick with config   * @param srcList   * @param configs   * @param <T>   * @return   */  public static <T> List<T> levelPickWithNewByConfig(List<T> srcList, Double[]... configs) {
    if (srcList == null || srcList.isEmpty()) {      return Collections.emptyList();    }    List<T> res = new ArrayList<>(srcList.size());
    int lastIndex = 0;    for (Double[] config : configs) {
      int modelLen = config[0].intValue();      /**获取长度大于等于有效长度 全额取出*/      if (modelLen <= config[1]) {        for (int m = 0; m < modelLen; m++) {          res.add(srcList.get(lastIndex + m));        }      } else {        /**区域内使用不重复随机算法pick*/        int randLen = config[1].intValue();        int tempModelLen = modelLen;        for (int m = 0; m < randLen; m++) {          int randNum = random.nextInt(tempModelLen);          res.add(srcList.get(randNum + lastIndex));          tempModelLen--;        }      }      lastIndex += modelLen;    }
    return res;  }
  /**   * pick   * @param srcList   * @param configs 取出配置   * @param pickNum 最大取出量   * @param <T>   * @return   */  public static <T> List<T> levelPickWithNew(List<T> srcList, Double[][] configs, ConfigTypeEnum typeEnum, Integer pickNum) {    if (pickNum < srcList.size()) {      return srcList;    }
    switch (typeEnum){      case FIXED_FIXED:        return levelPickWithNewByConfig(srcList, configs);      case JUST_PERCENT:        return levelPickWithNewByConfig(srcList, exchangeConfigToFixNum(srcList.size(), configs));      case PERCENT_FIXED:        return levelPickWithNewByConfig(srcList, exchangeConfigToFixNum(srcList.size(), pickNum, configs));    }    return srcList;  }
  public static <T> List<T> levelPickWithNew(List<T> srcList, Double[][] configs, ConfigTypeEnum typeEnum) {    return levelPickWithNew(srcList, configs, typeEnum, null);  }
  /**   * 将ConfigTypeEnum.PERCENT_FIXED转化成对应的FIXED_FIXED配置   * @param listLen   * @param configs   * @return   */  public static Double[][] exchangeConfigToFixNum(int listLen, Double[]... configs) {    Double[][] res = new Double[configs.length][configs[0].length];    int total = 0;    for (int i = 0; i < configs.length - 1; i++) {      int temp = (int) (configs[i][0] * listLen);      total += temp;      res[i][0] = (double) temp;    }    /**最后一个配置收拾残局*/    if (listLen > total) {      res[configs.length - 1][0] = (double) (listLen - total);    }    return res;  }
  /***   * ConfigTypeEnum.JUST_PERCENT转化成对应的FIXED_FIXED配置   * @param listLen   * @param pickNum   * @param configs   */  public static Double[][] exchangeConfigToFixNum(int listLen, Integer pickNum, Double[]... configs) {
    if (pickNum == null || pickNum < 0) {      throw new RuntimeException("pickNum not leagal !!!");    }    Double[][] res = new Double[configs.length][configs[0].length];    int total = 0;    int totalPick = 0;    for (int i = 0; i < configs.length - 1; i++) {      int temp = (int) (configs[i][0] * listLen);      int tempPick = (int) (configs[i][0] * pickNum);      total += temp;      totalPick += tempPick;      res[i][0] = (double) temp;      res[i][1] = (double) tempPick;    }    /**最后一个配置收拾残局*/    if (listLen > total) {      res[configs.length - 1][0] = (double) (listLen - total);    }    if (pickNum > totalPick) {      res[configs.length - 1][1] = (double) (pickNum - totalPick);    }
    return res;  }
  public enum ConfigTypeEnum {
    PERCENT_FIXED(1, "百分比-固定量"),    FIXED_FIXED(2, "固定量-固定量"),    JUST_PERCENT(4, "仅百分比"),;//必须传期待List大小(pickNum)
    private Integer type;    private String desc;
    ConfigTypeEnum(Integer type, String desc) {      this.type = type;      this.desc = desc;    }
    public Integer getType() {      return type;    }
    public void setType(Integer type) {      this.type = type;    }
    public String getDesc() {      return desc;    }
    private static final Map<Integer, ConfigTypeEnum> map = new HashMap<>();
    static {      for (ConfigTypeEnum enums : ConfigTypeEnum.values()) {        map.put(enums.getType(), enums);      }    }
    public static ConfigTypeEnum getEnumValue(int code) {      return map.get(code);    }
    public static String getDescByType(int code) {      return map.get(code).getDesc();    }
    public void setDesc(String desc) {      this.desc = desc;    }
  }
  public static void main(String... args) {
    Double[][] configs = { { 0.15d, 10.0d }, { 0.25d, 15.0d }, { 0.6d, 30.0d } };
    ConfigTypeEnum configType = ConfigTypeEnum.PERCENT_FIXED;  }}
复制代码
 有更好方式的小伙伴欢迎交流~~e:995517265@qq.com
划线
评论
复制
发布于: 2021 年 03 月 31 日阅读数: 9
版权声明: 本文为 InfoQ 作者【迟到的月亮】的原创文章。
原文链接:【http://xie.infoq.cn/article/fff44fcf2a0d12929706d8560】。文章转载请联系作者。

迟到的月亮
关注
还未添加个人签名 2020.03.30 加入
还未添加个人简介











 
    
评论