另一道腾讯的面试题
看到C#区此题讨论的比较火,转过来大家一起讨论讨论。
已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10,要求考虑每个数字出现的概率问题。
最近比较忙,很少上来看,为了庆祝国庆顺便散个分。
散分规则:
1、达到题目要求且给出算法说明的加分。
2、在第1点的基础上算法效率高的多加分。
3、只写出算法但没有说明的视情况加分。
[解决办法]
int rand10()
{
int nResult=0;
while(true)
{
nResult=rand7();
if(nResult<=5)
break;
}
while(true)
{
int n = rand7();
if (n==1)
continue;
else if(n>4)
nResult*=2;
else
nResult=nResult*2-1;
break;
}
return nResult ;
}
挺好,转贴过来,概率10%。
[解决办法]
1. 通过 rand7()*7+rand7() 产生 8 9 10 11 …… 51 52 53 54 55 56 这49个数,每个数的出现机率相等
2. 只需要前面 4*10 个数,所以舍弃后面的9个数
3. 将8 9 10 11 转化为 1,12 13 14 15 转化为 2,……,44 45 46 47 转化为 10。公式是 (a-4)/4
int rand10(){int a;while( (a=rand7()*7+rand7()) > 47 );return (a-4)/4;}
[解决办法]
代码例子
int rand10() { int r1, r2, r3=0; while (true) { r1 = rand7(); r2 = rand7(); r3 = (r1+r2)%10; if ((r3>5 || r3==0) && (Math.abs(r1-r2) <= (r3==8 ? 2 : 1))) continue; return r3+1; }}
[解决办法]
int num = rand7()+rand7()-1;if(num>=1&&num<=10) return num;
[解决办法]
package com.cn.mishi;import java.util.Random;public class RandomTest { public static void main(String[] args) { int i = getRandomNumber(); int j = getRandomNumber(); int n = i * 7 + j; int k = n * 10; if (k >= 0 && k < 49) { System.out.println(1); } else if(k >= 49 && k < 49 * 2) { System.out.println(2); } else if(k >= 49*2 && k < 49 * 3) { System.out.println(3); } else if(k >= 49*3 && k < 49 * 4) { System.out.println(4); } else if(k >= 49*4 && k < 49 * 5) { System.out.println(5); } else if(k >= 49*5 && k < 49 * 6) { System.out.println(6); } else if(k >= 49*6 && k < 49 * 7) { System.out.println(7); } else if(k >= 49*7 && k < 49 * 8) { System.out.println(8); } else if(k >= 49*8 && k < 49 * 9) { System.out.println(9); } else if(k >= 49*9 && k < 49 * 10) { System.out.println(10); } } private static int getRandomNumber() { Random r = new Random(); return r.nextInt(7); }}
[解决办法]
小弟给个建议,大家看看可行否
在函数里调用2次rand7(),然后做字符串拼接,应该会等机会得到下列49个数
11 21 .......... 71
12 22 .......... 72
13 23 .......... 73
14 24 .......... 74
15 25 .......... 75
16 26 .......... 76
17 27 .......... 77
然后取其中10个映射1-10,出现其它的过滤,这样1-10的概率每个应该为10%的。
简单 清晰。
[解决办法]
//除了0为4/49,其它的是5/49//(rand7()*7+rand7()-7)%10 for(int i=1;i<8;i++) { for(int j=1;j<8;j++) { System.out.printf("%2d,",(i*7+j-7)%10); } System.out.println(); }//结果如下: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
[解决办法]
我出个想法啊,rand7()产生1~7的区间,那么我将它产生的区间转换为0~1这个区间,然后再转换为1~10这个区间
[解决办法]
1. 通过 rand7()*7+rand7() 产生 8 9 10 11 …… 51 52 53 54 55 56 这49个数,每个数的出现机率相等
2. 只需要前面 4*10 个数,所以舍弃后面的9个数
3. 将8 9 10 11 转化为 1,12 13 14 15 转化为 2,……,44 45 46 47 转化为 10。公式是 (a-4)/4
这方法可行
[解决办法]
int rand10()
{
int a1 = rand7();
int a2 = rand7();
int a = a1 + a2;
if(a>10){
a = 10;
}
return a;
}
[解决办法]
新手来凑个热闹,我想用10次rand7(),加起来,应该是10到70中的任意一个数,
然后取除10取余数,余数应该是0到9之内的任意一个数吧,然后再加1
int rand10()
{
int a = rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7()+rand7();
return a%10+1;
}
新手,要是错了的话,指出来就可以,别笑话~
[解决办法]
rand7()
可以这样来,0-0.7 1
0.7-1.4 2
1.4-2.1 3
2.1-2.8 4
2.8-3.5 5
3.5-4.2 6
4.2-4.9 7
4.9-5.6 8
5.6-6.3 9
6.3-7 10
太该就这意思,还需改进。。。。。
[解决办法]