一个编程面试题,只要写出伪代码就可以了

假设有如下两个函数 rand3()可以产生随机的0 1 2,rand5()可以产生随机的0 1 2 3 4,现在请你利用它编写一个函数rand7(),产生0~6的随机数

为了使随机数字产生的概率均等:

 int rand7()
{
    int sum=0;
    sum+=rand3();//0,1,2
    sum+=rand3()+3;//3,4,5
    sum+=rand3()+6;//6,7,8
    sum+=rand5()+9;//9,10,11,12,13
    sum%=7;//0,1,2,3,4,5,6
    return sum;
}

rand7=rand3+rand5
rand7=rand3+rand3+rand3
rand7=rand3*2+rand3
rand7=rand3*3-rand5
应该还有一些,

 int rand7()
{
    int x5 = 7;
        while (x5 > 6)
        {
    int x3 = 2;
        while (x3 > 1)
        {
            x5 = rand(5);
                if (x3 == 1) x5 = x5 + 5;
                if (x5 < 7) return x5;
        }
        }
}

int a=rand5+rand5+…+rand5 + rand3+…+rand3
return a%8;

个数自己决定。

第一枚骰子有三种可能,第二枚骰子有五种可能,排列组合有十五种可能,取其中的七种或十四种,剩下的抛弃不就行了,只要保证七分之一或者十四分之一,反正是电脑运行,有什么资源浪费的

int rand7()
{
int x5 = rand5();
int x3 = rand3();
while (x5 ==x3 ) {
int x3 = rand3();

}
return x5+x3;
}

int rand7()
{
int x5 = rand5();
int x3 = rand3();
while (x5 ==x3 ) {
x3 = rand3();

}
return x5+x3;
}

int rand7()
{
int x3=rand3();
int x5=rand5();
if(x3=x5)
return x3;//或者return x5;
else
return x3+x5;
}

这样不知道行不行

 int rand7() {

 int sum = 0;
 for (int i=0;i<7*5;i++) {
sum+= rand3()+i*3;
 }
 for(int i=0;i<7*3;i++) {
 sum += rand5()+i*5;
 }


 return sum%7;

 }

参考了楼上的

int rand7(){
bool flag = true;
while(flag){
flag = false;
int a = rand3()+rand5();
int b;
if(a==0||a==6)//处理0、6
return a;
else if(a==1||a==5)//处理1、5
{
while(true){
b = rand3();
if(b==0)
return a;
else if(b==1)
{
flag = true;
break;
}
}
}
else{//处理2、3、4
b = rand3();
if(b==0)
return a;
else
flag = true;
}
}
}

不是那么完美:

 int rand7()
{
    int sum;
    switch(rand3())
    {
    case 0:
        sum=rand5();//0,1,2,3,4
        break;
    case 1:
        sum=rand5()+5;//5,6,7,8,9
        break;
    case 2:
        do
        {
            sum=rand5()+10;//10,11,12,13,14
        }while(sum!=14);
        break;
    }
    sum%=7;//0,1,2,3,4,5,6
    return sum;
}

优化了的方法

 //从均匀的0~20里面取mod
int rand7() {

    int sum = 0;
    for (int i=0;i<7;i++) {
        sum+= rand3()+i*3;
    }
    return sum%7;
}

//从均匀的0~34里面取mod
int rand7() {

    int sum = 0;
    for(int i=0;i<7;i++) {
        sum += rand5()+i*5;
    }
    return sum%7;
}

调用rand3函数7次,统计某一个数字(例如0)在其中出现的的次数,将次数作为随机数
int rand7(){
int count = 0;
--这里统计数字0出现的次数
for(i=0;i<7;i++){
int b = rand3();
if(b==0){
count ++;
}
}
return count;
}

利用预置数组
int rand7(){
int a[][]={
0,1,2,
3,4,5,
6,0,1,
2,3,4,
5,6,7}
int row=rand5;
int col =rand3 ;
int rand7=7;
while(rand7=7){
rand7=a[row][col];
}
return rand7;
}

利用预置数组
int rand7(){
int a[][]={
0,1,2,
3,4,5,
6,0,1,
2,3,4,
5,6,7}
int row=rand5;
int col =rand3 ;
int rand7=7;
while(rand7=7){
rand7=a[row][col];
}
return rand7;
}

int rand7()
{
return rand3() + rand5();
}

int rand7()
{
return rand3() + rand5();
}
原理:
rand3 ——》0,1,2
rand5 ——》0,1,2,3,4
两者最大值为2+4=6
两者最小值为0+0=0
因为是随机数,因此无需知道每次都是多少,只要结果正确即可。即rand3+rand5

看了这么多答案,也真是挺让人眼花的,各种类型的都有,按概率偏差的特点可以分为: 单峰形、双峰形、递减形、起伏形,真是万紫千红啊!其实已经有网友提供了一个正确的答案,各位自行查找。
我就按99999次统计算来测试,看看以上各位能不能对得上号,第一组数据 Test rand5 9999 是正常的测试,作为对比组:
Test rand5 9999
0 -> 2024 20.24%
1 -> 1972 19.72%
2 -> 2019 20.19%
3 -> 1989 19.89%
4 -> 1995 19.95%

Test rand7 99999
0 -> 13457 13.46%
1 -> 17075 17.08%
2 -> 18373 18.37%
3 -> 17059 17.06%
4 -> 13332 13.33%
5 -> 10401 10.40%
6 -> 10302 10.30%
Test rand7a 99999

1 -> 19865 19.87%
2 -> 20100 20.10%
3 -> 26499 26.50%
4 -> 13475 13.48%
5 -> 13320 13.32%
6 -> 6740 6.74%

Test rand7b 99999
0 -> 6621 6.62%
1 -> 13241 13.24%
2 -> 19854 19.85%
3 -> 19984 19.98%
4 -> 20137 20.14%
5 -> 13399 13.40%
6 -> 6763 6.76%

Test rand7c 99999
0 -> 46422 46.42%
1 -> 13540 13.54%
2 -> 13346 13.35%
3 -> 6675 6.68%
4 -> 6602 6.60%
5 -> 6687 6.69%
6 -> 6727 6.73%

Test rand7d 99999
0 -> 17897 17.90%
1 -> 16879 16.88%
2 -> 13466 13.47%
3 -> 10974 10.97%
4 -> 10920 10.92%
5 -> 13499 13.50%
6 -> 16364 16.36%

Test rand7e 99999
0 -> 14284 14.28%
1 -> 14205 14.21%
2 -> 14245 14.25%
3 -> 14409 14.41%
4 -> 14316 14.32%
5 -> 14347 14.35%
6 -> 14193 14.19%

Test rand7f 99999
0 -> 3708 3.71%
1 -> 11277 11.28%
2 -> 22269 22.27%
3 -> 25953 25.95%
4 -> 22133 22.13%
5 -> 10943 10.94%
6 -> 3716 3.72%

看了各位算法经测试,楼上预置数组的方法是正确的:

 #include<stdlib.h>
#include<stdio.h>
#include <time.h>
int rand5()
{
    return rand()%5;
}

int rand3()
{
    return rand()%3;
}
int rand7()
{
    int a[5][3]={
        0,1,2,
        3,4,5,
        6,0,1,
        2,3,4,
        5,6,7};
    int row,col;
    do 
    {
        row = rand5();
        col = rand3();
    } while(a[row][col]==7);

    return a[row][col];
}

int main()
{ 
    int re[7]={0};
    srand( (unsigned)time( NULL ) );
    for(int i=0;i<100000;i++)
    {
        re[rand7()]++;
    }

    for(int i=0;i<7;i++)
    printf("re[%d]=%d, %2d%%\n",i,re[i],int(re[i]/1000.0+0.5));
    return 0; 
}

 int rand7() {

    while (true) {
        switch (rand3()) {
            case 0:
                return rand3();     //0,1,2
            case 1:
                return rand3()+3;   //3,4,5
            case 2:
                if (rand3()) {      // 取到7,8重新取
                    continue;
                }
                return 6;           // 6
        }
    }
}

修正:

 int rand7()
{
    int sum;
    do
    {
        switch(rand3())
        {
        case 0:
            sum=rand5();//0,1,2,3,4
            break;
        case 1:
            sum=rand5()+5;//5,6,7,8,9
            break;
        case 2:
            sum=rand5()+10;//10,11,12,13,14
            break;
        }
    }while(sum==14);
    sum%=7;//0,1,2,3,4,5,6
    return sum;
}

关于这个问题,结合各家给的参考答案,我专门写了一篇博文,有兴趣可以移驾《一个随机数引发的血案》:http://blog.csdn.net/WinsenJiansbomber/article/details/50604653

这个更简单点:

 int rand7()
{
    int re;

    do
    {
        re=rand3()+rand3()*3;
    }while(re>6);

    return re;
}