一道腾讯的面试题
已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10。
[解决办法]
1/7的概率得到1,2
3/7的概率得到4,6,8,10
3/7的概率得到3,5,7,9
这个概率明显不是每个数都是10%
[解决办法]
刚刚理解错了。
。。。。
应该是对的。每个数的概率相同。。。
但是可能存在一个问题,两个while里面产生的随机数会相同,如果运行太快的话
[解决办法]
class Program { static void Main(string[] args) { Console.WriteLine(Rand10()); Console.Read(); } static int Rand10() { Random ran = new Random(); return ran.Next(0, 3) + Rand7(); } static int Rand7() { Random ran = new Random(); return ran.Next(1, 7); } }
[解决办法]
好像要完全利用Rand7,那我搞错了
[解决办法]
做两次随机.将它们看做二位7进制数的两个位,那么这个7进制数可以表示的最大值为:
6*7 + 6 = 48;然后把这个数10等分即4.8,即可建立一个区间的对应关系.
前面说那么复杂其实就是算出这个数的10进制值除去4.8 丢弃小数位后+1...
int rand10 (){
return ((int)(((rand7()-1)*7 + (rand7()-1)) / 4.8)) + 1;
}
[解决办法]
汗..搞懵了.
因为要+1,所以要除的应该是48 / 9 ≈ 5.3333333...
[解决办法]
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication2{ class Program { static Random r = new Random(); static void Main(string[] args) { Console.WriteLine("".PadLeft(20, '=')); TestRnd(rand7); Console.WriteLine("".PadLeft(20, '=')); TestRnd(rand10); Console.WriteLine("".PadLeft(20, '=')); } static int rand7() { return r.Next(1, 8); } static int rand14() { int r = 0; while (r < 6) { r = rand7(); } if (r == 6) return rand7() * 2 - 1; else return rand7() * 2; } static int rand10() { int r = 11; while (r > 10) { r = rand14(); } return r; } static void TestRnd(Func<int> RndFunc) { Enumerable.Range(0, 1000000) .Select(x => RndFunc()) .GroupBy(x => x, (x, y) => new { x, y = y.Count() / 1000000.0 }) .OrderBy(x => x.x) .ToList() .ForEach(x => Console.WriteLine("{0} 概率 {1:0.0000}", x.x, x.y)); } }}
[解决办法]
我的算法从理论上说肯定是正确的。
假设rand7返回1~7是真正的随机数(当然我的程序用的是伪随机数)。
那么出现6和出现7的概率是相等的。
所以可以用这个将1~7延展到1~14。可以证明 rand14 得到 1~14 的概率是均匀的。都是P1 = 1/14。
P2 = P(x <= 10)的概率是 10/14。
根据古典概型
求得 P = P(P1|P2) = P1 / P2 = 1 /10
[解决办法]
而且我们可以得到一般规律
根据 RndM 得到 RndN
如果 M > N,那最简单,只要剔除 M > N 的数据,返回就可以了。
如果 M < N,首先用延展方法将 M 延展到 xM,xM > N
然后再用上面的办法获取。
另外1L和2L的代码似乎也是对的。
[解决办法]
double A,B;
A=rand7();
B=A/2.0+0.5+(A-1);
[解决办法]
7*7=49
1~40 => 1~10
41~49被抛弃,继续循环
------解决方案--------------------