由rand_a()实现rand_b()

简介: 前言阿里的一道随机数生成的题目,这里进行一下解释 题目给定了rand7,如何生成rand3? 思路一个非常直观的思路,就是不断的调用rand7,直到它产生1-3之间的数,然后返回。

前言

阿里的一道随机数生成的题目,这里进行一下解释
 

题目

给定了rand7,如何生成rand3?
 

思路

一个非常直观的思路,就是不断的调用rand7,直到它产生1-3之间的数,然后返回。代码如下:(如果有同学说这里没有3,但是不代表我不能判断和3的大小比较吧)
 
[cpp]  view plain copy
 
  1. #include <stdio.h>  
  2.   
  3. int rand_3()  
  4. {  
  5.     int x;  
  6.   
  7.     while (x = rand_7()) {  
  8.         if (x <= 3) {  
  9.             return x;  
  10.         }  
  11.     }  
  12. }  

接下来,就是判断rand_3是否能等概率的产生1,2,3.也就是我们需要计算产生1,2,3的概率是否都是1/3.
 
首先,rand_7可以等概率的产生1-7,我们以rand_3生成1为例,假设:
  • 第一次生成1的概率是1/7
  • 第二次生存1的概率是4/7 * 1/7,因此第一次肯定是生成了大于3的数例如4,5,6,7,概率是4/7
  • 同理,第三次生成1的概率是(4/7)^2 * 1/7
因此,rand_3生成1的概率是P(x=1)= 1/7 +  (4/7) * 1/7 + (4/7)^2 * 1/7 + ... + (4/7)^n-1 * 1/7 //等比数列
                                                  =  1/7 * ((1 - (4/7)^n) / 1 - 4/7) = 1/7 * 7/3 = 1/3
 
同理,可验证生成2,3的概率均为1/3
 

结论

上述证明说明rand3可以等概率的产生1,2,3.从上面的分析,我们可以得出一个更一般的结论:
 
如果a>b,我们一定可以用rand_a去实现rand_b.其中,rand_a是等可能的生成1-a,rand_b是等可能的生成1-b
 
 

扩展

 
现在给定两个生成随机数的函数rand_a和rand_b,rand_a和rand_b分别产生1-a和1-b的随机数,a和b不相等,现在让你用rand_a实现rand_b,方法如下:
  1. 如果a>b,则可以直接采用上述方法
  2. 如果a<b, 则构造rand_a^2=a * (rand_a - 1) + rand_a,表示生成1-a^2的随机数,如果a^2还小于b,那么继续构造rand_a^3=a * (rand_a^2 - 1) + rand_a
 

举例说明

阿里2014年笔试题目,是给定生成1-7的随即函数rand_7,看是否能生成其它随机数?
 
我们先看一下是否能等概率生成1-49,构造rand_49 = 7 * (rand_7 - 1) + rand_7 (ps:别问我7从哪里来的,rand_7既然能随即生成1-7,我当然可以获得到7了)
 
rand_7 - 1能等概率的生成0, 1, 2, 3, 4, 5, 6,每个数的生成概率都是1/7,所以*7之后,可以等概率的生成0,7,14,21,28,35,42,每个数的概率都是1/7
 
既然0,7,14,21,28,35,42每个数的概率都是1/7,当每个数都加上+rand_7之后,则1-49是等概率产生的,1/7 × 1/7 = 1/49,中间不会出现重复数据
 
所以,我们用rand_7产生了rand_49,有了rand_49,按照最初上面过滤的方法,我们当然可以获得任何小于49的随机函数
 
目录
相关文章
|
3月前
|
Java
成随机数的几种方法、Math.random()随机数的生成、Random()的使用
这篇文章介绍了生成随机数的三种方法:使用`System.currentTimeMillis()`获取当前时间的毫秒值来生成0到100的随机整数、使用`Math.random()`生成[0,1)范围内的`double`类型随机数并扩大到指定范围、以及使用`Random`对象的`nextInt()`方法生成指定范围内的随机整数,并提供了相应的Java代码示例和测试结果。
成随机数的几种方法、Math.random()随机数的生成、Random()的使用
|
6月前
|
算法 安全 大数据
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析(二)
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析
193 0
|
6月前
|
算法 安全 数据安全/隐私保护
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析(一)
【C/C++ 随机函数行为】深入探索C++中的随机数:std::random_device与rand的行为分析
456 0
|
存储 算法 C语言
你不了解的随机函数rand
你不了解的随机函数rand
119 0
|
存储 C++
【C/C++】如何生成随机数?带你深入了解rand函数
【C/C++】如何生成随机数?带你深入了解rand函数
237 0
LeetCode 470. 用 Rand7() 实现 Rand10()
已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。
86 0
|
JavaScript 前端开发
Math.random();
Math.random();
97 0
|
编译器 C语言 C++
C++中rand随机数的用法
C++标准函数库提供一随机数生成器rand,返回0-RAND_MAX之间均匀分布的伪随机整数。 RAND_MAX必须至少为32767。rand()函数不接受参数,默认以1为种子(即起始值)。 随机数生成器总是以相同的种子开始,所以形成的伪随机数列也相同,失去了随机意义。(但这样便于程序调试)
Random类和Math.random生成的随机数
Random类和Math.random生成的随机数
208 0
【LeetCode】用 Rand7() 实现 Rand10()
【LeetCode】用 Rand7() 实现 Rand10()
129 0