随机数:关于用Rand7生成Rand10的最准确的算法(MS中的一道题)--仿真证明

1 篇文章 0 订阅
1 篇文章 0 订阅

今天同学出了这样一个题,让我们大家来讨论,大家都提出了很多方法,最后在CSDN上搜了一个相关的帖子,感觉上面写的算法挺杂的,想看原帖的如下

其实有一个非常有说服力的算法,实现也比较也比较简单。就是利用我们学计算机的基础--进制(2进制,8进制等)思想来完成的。

前提有一个普适的规律:1、任何一个进制类型都可以表示任意一个数字。

                                            2、进制的每一位上的数,出现的值范围都是一样的,如2进制,每位中只能出现0,1;8进制,每位中只能出现0~7;7进制,每位上出现0~6中的数是概率都是相等的。

基于以上的2个规律,得到了以下两种较准确的算法。

1.取0~39内的数除于4取整,得到范围为0~9(每个取值的数都是机会均等的)

代码如下:

int rand10()
{
    int i;
    int j;
    int Tworesult;//表示的两位7进制,其十进制的范围是0~48 
    do
    {
       i = rand7() - 1;
       j = rand7() - 1;
       Tworesult = i * 7 + j;
    }
    while(Tworesult >= 40);
    return Tworesult/4 + 1;
}

仿真100w次的结果如下:

1次数:99938
2次数:99523
3次数:100191
4次数:99723
5次数:100169
6次数:99864
7次数:100732
8次数:99854
9次数:100134
10次数:99872

如果将上面程序的最后一句改为 Tworesult %10 + 1;

100w次的仿真结果如下:

1次数:100075
2次数:100447
3次数:99600
4次数:99535
5次数:100685
6次数:99633
7次数:100121
8次数:99920
9次数:100034
10次数:99950

两者的结果其实是一样的

2.取40~49的数取模10(mod(10)),得到范围的0~9(每个取值的数都是机会均等的)

int rand10()
{
    int i;
    int j;
    int Tworesult;//表示的两位7进制,其十进制的范围是0~48 
    do
    {
       i = rand7() - 1;
       j = rand7() ;
       Tworesult = i * 7 + j;
    }
    while(Tworesult < 40);
    return Tworesult%10 + 1;
}

100w的仿真结果如下:

1次数:100171
2次数:100506
3次数:99827
4次数:99713
5次数:99875
6次数:99979
7次数:100454
8次数:100043
9次数:99675
10次数:99757

总结:
这两种方法都达到了题目要求的效果,但是对于大量数据统计而言,算法1的时间效率明显要高于算法2

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值