遇到的随机数问题

随机数

最近老是看到生成随机数,随机打乱的面经
来自己总结一下

Random的实现原理

首先看java里面的Random是怎么实现的

看到这里有一个原子类的seed,和两个16进制不可变的值,还有一个mask,47位1
在这里插入图片描述

然后无参构造函数,调用的这两个函数就是为了生成一个随机的值:
在这里插入图片描述

无参构造,调用的是有参构造函数,用来初始化seed的值
在这里插入图片描述

在这里插入图片描述

然后看一下常用的生成随机整数的方法,调用的是next()
在这里插入图片描述

然后看next(),里面的逻辑就是,获取到seed种子,然后生成的下一个种子nextseed就等于下面这个公式计算出来的一个值,虽然muliplier和addend的值不知道怎么取的,但是可以看出这个随机其实也是一个伪随机的
在这里插入图片描述
在这里插入图片描述

另外,给定一个边界生成随机数
如果给定的边界正好是一个2的幂次方,那么就直接移位
如果不是2的幂,那么就取余r = u % bound
在这里插入图片描述

产生高强度的随机数,有两个重要的因素:种子和算法。算法是可以有很多的,通常如何选择种子是非常关键的因素。 如Random,它的种子是根据时间来实现的,所以它的随机数都是可预测的, 是弱伪随机数。
强伪随机数的生成思路:收集计算机的各种信息,键盘输入时间,内存使用状态,硬盘空闲空间,IO延时,进程数量,线程数量等信息,CPU时钟,来得到一个近似随机的种子,主要是达到不可预测性。

这篇文章说的比较详细:
https://my.oschina.net/hosee/blog/600392

将数组随机打乱

我想到的方法就是产生一个随机数,然后对数组中元素个数n取余数,所得的数就是本次随机的位置
然后取出这个元素,放在结果数组的第一个位置
然后继续产生随机数对n - 1取余数,得到第二个位置
以此类推,生成一个随机的结果数组

然后去查了一下,发现更好的方法是遍历一遍数组,
产生一个随机数,对n取余后,得到一个下标idx
然后与i位置的元素交换

		Random random = new Random(6);

        int[] nums = {1,2,3,4,5,6};
        for(int i = nums.length; i >= 1; i--){
            int idx = random.nextInt(i);
			//swap
            int temp = nums[i - 1];
            nums[i - 1] = nums[idx];
            nums[idx] = temp;
        }

还有一种是用排序的方法,这个可能不太严谨,但是要get到这个思想
具体见:https://www.cnblogs.com/macq/p/6650586.html

		List<Integer> list = new ArrayList<>();
        for(int i = 1; i < 10; i++){
            list.add(i);
        }
        Collections.sort(list, (a, b) -> (Math.random() - 0.5) > 0 ? 1 : -1);
        System.out.println(list);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值