洗牌算法-交换法

洗牌算法-交换法

即费雪耶兹(Fisher–Yates) 也被称作高纳德( Knuth)随机置乱算法


算法目的

  • 描述一:获得[n,m]区间的k个不重复随机数/元素(获取不重复随机数)。
  • 描述二:将[n,m]区间的m-n个数随机置乱(随机数置乱)。

算法思想

​ 该算法每轮从序列可选范围中随机选取一个元素放入目标序列中,然后将该元素与序列可选范围中最后一个元素相交换(如果随机选中的是序列可选范围最后的元素,则相当于没有发生交换),再把序列可选范围减1。重复此过程,直到填满目标序列为止。

限制性条件

  • n<m
  • k<=m-n
  • 序列可选范围初始时为整个初始序列的范围

算法示例


  • 目标

    从[0,9]区间随机生成5个不重复随机数

  • 初始序列

    0 1 2 3 4 5 6 7 8 9

  • 执行流程

    第一轮

    0 1 2 3 4 9 6 7 8 | 5 ---> 5

    第二轮
    0 1 2 3 4 9 8 7 | 6 5 ---> 5 6

    第三轮
    0 1 2 3 4 7 8 | 9 6 5 ---> 5 6 9

    第四轮
    0 8 2 3 4 7 | 1 9 6 5 ---> 5 6 9 1

    第五轮
    0 8 2 7 4 | 3 1 9 6 5 ---> 5 6 9 1 3

  • 得到目标序列

    5 6 9 1 3

  • 实现

java代码:

//生成10个0-9间不重复随机数
static int[] defult = new int[100]; 
//初始化可选范围
static int range=100;

public static void main(String[] args) {
    //目标数组
    int[] targetArray = new int[100];
    //初始化默认数组
    for(int i=0;i<defult.length;i++) {
        defult[i]=i;
    }
    
    Random ran = new Random(100);
    
    for(int i=0;i<targetArray.length;i++) {
        int ranNum =ran.nextInt(range); 
        targetArray[i]=defult[ranNum];
        swap(ranNum,defult.length-i-1);
        range--;
    }
    
    for(int i=0;i<targetArray.length;i++) {
        System.out.println(targetArray[i]);
    }
    
}

//交换
public static void swap(int startPosition,int endPosition) {
    int temp = defult[startPosition];
    defult[startPosition] = defult[endPosition];
    defult[endPosition]=temp;
}

转载于:https://www.cnblogs.com/wangzhijun97/p/9346939.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值