用一个随机数函数去生成另一个随机数函数:rand(a)生成rand(b)以及rand(a,b) 生成rand(c,d)

25 篇文章 2 订阅

让我们把这个问题泛化一下,从特殊到一般。现在我给你两个生成随机数的函数Randa, Randb。Randa和Randb分别产生0到a的随机数和0到b的随机数,a,b不相等 (相等就没必要做转换了)。现在让你用Randa实现Randb。

首先当  a>b  , 时,最简单的就是通过:  

int x=a;
while(x>b)
{
    x=randA();
}
return x;

即只输出在0-b范围内的情况,但是对于a,b相差很大的情况,会导致循环随机多次,时间消耗太多,做了 太多次不必要的随机。

那么改进的方法就是:将范围设置为最接近a的一个能被b整除的数n,譬如a=120,b=7时,n取b*(a/b) 119       

这样只需要return  x%b取余的结果即可 等概率输出0到b-1

 

通过上文分析,我们可以得到步骤如下:

  1. 如果a > b,进入步骤2;否则构造Randa2 = a * (Randa – 1) + Randa, 表示生成1到a2(a平方) 随机数的函数。  

  2. 如果a2 仍小于b,继教构造 Randa3 = a * (Randa2 – 1) + Randa…直到ak > b   a的k次方大于b,这时我们得到Randak , 我们记为RandA。

  3. 步骤1中我们得到了RandA(可能是Randa或Randak ),其中A > b, 我们用下述代码构造Randb:

// A > b

int Randb(){

int x = ~(1<<31); // max int

while(x > b*(A/b)) // b*(A/b)表示最接近A且小于A的b的倍数

x = RandA();

return x%b ;

}
 

从上面一系列的分析可以发现,如果给你两个生成随机数的函数Randa和Randb, 你可以通过以下方式轻松构造Randab生成1到a*b的随机数。

  1. Randab = b * (Randa - 1) + Randb

  2. Randab = a * (Randb - 1) + Randa

  3. 这是因为组合成1-a*b结果是等概率的

 

另一个问题:给定一个randA函数可以随机生成0-A之间的数,去实现一个randBC(随机生成B-C的数):

问题可以转换为       生成一个rand(c-b)的函数,因为rand(c-b)+b 即可等概率表示b到c之间的数

 

如果再一般化一下,我们还可以把问题变成:给你一个随机生成a到b的函数, 用它去实现一个随机生成c到d的函数。

 

问题可以转换成已知一个rand(b-a)的函数,生成一个rand(d-c)的函数

因为randab()=rand(b-a)+a        ;    randcd()=rand(d-c)+c

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溯夜流云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值