关于面试中经常出现的根据一个随机数构造另外的随机数的解法
source link: https://www.leftpocket.cn/post/interview/rand/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
之前做了一些Tencent
及几家公司的面试题,发现有一种关于产生随机数的类型的题目。看到多有大牛们做出来,而且效率很高,也有不知道怎么做的,最近根据几个产生随机数的题目整理一下,发现所有的类似题目的解法类似,故分享一下。
这里给出三道题目,希望你看完之后能够豁然开朗,再也不用怕类似的题目。
题目一、如何用一个1-8随机数生成器制作一个1-7随机数生成器?
这是我在知乎上看到的一道题,实际上这到底相当简单。从大的随机数制作小的随机数是很简单的。
这种最简单,因为需要生成的随机数是一个子集,所以直接把不在某个范围的去掉就行了。生成的数也是随机的。
func rand7() int32 {
var result int32
for {
res := rand8()
if res <= 7 {
result = res
break
}
}
return result
}
// 1->8
func rand8() int32 {
return 1 + rand.Int31n(8)
}
题目二、给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数。
利用随机函数rand()函数生成一个等概率随机生成整数1到5的函数Rand5(),然后根据Rand5()生成Rand7(),代码如下:
func rand5() int32 {
return 1 + rand.Int31n(5)
}
func rand7() int32 {
var (
n int32
tmp1, tmp2 int32
)
for {
tmp1 = rand5()
tmp2 = rand5()
n = (tmp1-1)*5 + tmp2 //n是可以取1~25的随机数
if n <= 21 {
break
}
}
return 1 + n%7
}
算法的关键就是两次运用rand5()
那我们又是怎么保证结果的每一个数字的随机概率是一样的呢。
- (tmp1-1)*5,结果只有5种可能:(0,5,10,15,20), 每个的概率是20%
- tmp2,结果也是5种可能:(1,2,3,4,5),每个的概率是20%
- 我们任选一个数字,比如13,它只有一种构造的可能,那就是10+3,也就是
20%*20%=0.04
这个算法的核心就是 x5,这个5也就是rand5的最大值,它保证了两个随机数的值为任意一个数字的可能性只有一种,可以保证概率的相等性。
我们千万别用两个随机数简单相加,因为相加后,某个数字出现的可能就不只一种了。 比如:rand5+rand5
- 任取一个数字7,可能是2+5,3+4,4+3,5+2,四种可能。概率是6/25=24%
- 任取一个数字10,可能只可能是5+5,一种可能。概率是1/25=4%
题目三、已知rand7() 可以产生 1~7 的7个数(均匀概率),利用rand7() 产生rand10()
解法与上面类似,同样只用两个rand7()生成rand10()即可。各位可以自己试试。 另外,看见一个大牛的方法,似乎比以上更为简单,现贴出代码,供各位欣赏:
其实跟上面的方式类似,只是它是先截取,再计算。把顺序调换了一下。
int rand10()
{
int temp1;
int temp2;
do
{
temp1 = rand7();
}while(temp1>5);
do
{
temp2 = rand7();
}while(temp2>2);
return temp1+5*(temp2-1);
}
个人觉得两种方法有异曲同工之妙,所以大多数利用一个等概率随机数构造另外一个等概率随机数,只需两次使用概率函数即可。
<全文完>
Recommend
-
71
java分布式 Java高并发 Java高可用 Java高扩展 高并发架构NIO通讯spring boot
-
40
在以太坊应用中,游戏一直都是热点中的热点,而在游戏中,随机数往往是一个不可或缺的功能,比如骰子游戏中,我们需要通过随机数来控制点数,如果一个游戏有一个好的随机数算法的话,那么既可以保证游戏庄家不被黑,也可以保证玩家不被宰...
-
34
Python - @commoccoom -
-
2
位运算这个概念并不陌生,大多数程序员在进入这个领域的时候或多或少都接触过位运算,估计当时都写过不少练习题的。 位运算本身不难,困难的是大家没有学会在系统设计时用上它,提高系统性能,增加你的不可替代性。 就不做太多铺垫了,直接说下今...
-
7
关于java单线程经常占用cpu 100%的分析容器内就获取个cpu利用率,怎么就占用单核100%了呢背景:这个是在centos7 + lxcfs 和jdk11 的环境上复现的。下面列一下我们是怎么排查...
-
1
从字面意思理解就是数据不需要来回的拷贝,大大提升了系统的性能;这个词我们也经常在java nio,netty,kafka,RocketMQ 等框架中听到,经常作为其提升性能的一大亮点; 下面从I/O的几个概念开始,进而在分析零拷贝。 I/O概念 1.缓冲区...
-
9
V2EX › NAS Qnap 的同步工具 Qsync 同步过程中经常出现重复文件并有“冲突”字样,导致无限复制文件 ku...
-
5
V2EX › 宽带症候群 访问 V2EX 经常出现失败,多刷几下就正常了。忘了开启了 ipv6
-
5
关于 Math.random()生成指定范围内的随机数的公式推导 在 java 中,用于生成随机数的 Math 方法 random()只能生成 0-1 之间的随机数,而对于生成指定区间,例如 a-b 之间的随机数,却只能用相关计算...
-
0
【社长jing了!Vol.179】我一个老年人,经常半夜五杀很合理吧 趣闻...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK