随即数问题Rand7得到rand10

论坛中看到了帖子,http://topic.csdn.net/u/20111001/05/3d6fac8d-21ec-4dda-ad15-7a7076065e32.html

内容如下:

rand7是一个能生成1-7的随机数。要求利用rand7生成1-10的随机数。
之前看过这贴子,找不到了。。。再来问问。
要求:
不可以用这样的方法: 生成rand7() 如果 rand7()>5。重新来过。我的意思是要确保你的函数在任何的情况下都能在一个流程产生结果(可以用多次rand7())。总之就是不准有无限递归或循环。
之前也看到过这道题尝试了一下没有什么思路,但是经过看到10楼回帖发现一个思路很好,但是他们没有继续推敲下去还存在问题,因为得到的随机数中2,3的概率是大于其他的。

10楼回复:

 
int rand10() { int sum=0; for(int i=0; i<10; i++) sum=7*sum+rand7()-1; return sum%10+1; } 

 

 

 

首先这里的循环10次没有根据,但引用了7进制的 方法,可以保证得到的数是均匀分布的只是6666666666(7进制表示)是不可以被10整除的,余数为2,所以得到2,3的概率是大于其他的数。

但是这个思路是可以引用的,只要保证得到7进制数的最大值是10的倍数即可。经计算器尝试,4位数即可。也就是6666(7的4次幂是2401,所以6666=7的4次幂-1所以为2400)换成10进制为2400.得到数的区间为0-2400且均匀分布。所以这样取余后得到的rand10保证概率相同。

改进后代码如下:

 

int rand10()
{
  int sum=0;   
  for(int i=0; i<4; i++)
      sum=7*sum+rand7()-1;
  return sum%10+1;
}

 

20190731再翻出来看发现存在误区

产生的数据2401个,实际并不是概率平均。1-10,11-20,。。。。2391-2400.实际0的概率大。

如果采用7进制则需要数据分布为0-9,10-19,这样9结尾的数据才可以。但7是奇数所以不会产生0结尾的数(7的n次幂-1=0则需要7的n次幂为0结尾)。被PASS掉了。

如果8进制则可以为1-10,11-20,这样可以被10整除的数即可。8进制感觉也不会产生10结尾的数呢?

无解了待续

如果采用丢弃0,则均匀分布单不符合楼主不可丢弃的要求。

 

 

 

 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值