首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

一道腾讯的面试题,该怎么处理

2012-02-27 
一道腾讯的面试题已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10。[解

一道腾讯的面试题
已知有个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里面产生的随机数会相同,如果运行太快的话
[解决办法]

C# code
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...
[解决办法]
探讨
汗..搞懵了.
因为要+1,所以要除的应该是48 / 9 ≈ 5.3333333...

[解决办法]
此楼错误,正解在13楼。

code=C#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(Rnd10);
Console.WriteLine("".PadLeft(20, '='));
}

static int rand7()
{
return r.Next(1, 8);
}

static int Rnd10()
{
return (rand7() * 7 + rand7()) % 10 + 1;
}

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));
}
}
}code
====================
1 概率 0.1425
2 概率 0.1431
3 概率 0.1428
4 概率 0.1434
5 概率 0.1433
6 概率 0.1426
7 概率 0.1423
====================
1 概率 0.1019
2 概率 0.1022
3 概率 0.1019
4 概率 0.1020
5 概率 0.1021
6 概率 0.1020
7 概率 0.1021
8 概率 0.0812
9 概率 0.1022
10 概率 0.1024
====================
Press any key to continue . . .
[解决办法]
探讨

C# code

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;
b……


[解决办法]
探讨
C# code

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(Rnd10); Console.WriteLine("".PadLeft(20, '=')); } static int rand7() { return r.Next(1, 8); } static int Rnd10() { return (rand7() * 7 + rand7()) % 10 + 1; } 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)); } } }


====================
1 概率 0.1425
2 概率 0.1431
3 概率 0.1428
4 概率 0.1434
5 概率 0.1433
6 概率 0.1426
7 概率 0.1423
====================
1 概率 0.1019
2 概率 0.1022
3 概率 0.1019
4 概率 0.1020
5 概率 0.1021
6 概率 0.1020
7 概率 0.1021
8 概率 0.0812
9 概率 0.1022
10 概率 0.1024
====================
Press any key to continue . . .

[解决办法]
上面那个是错的,这个应该对了。

不过应该不是最好的方案。

C# code
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被抛弃,继续循环
------解决方案--------------------


探讨
7#楼的思路很清晰!

[解决办法]
说白了这个面试题考的就是你大学《概率论》有没有学过。

和编程没有什么关系。不懂概率论,看程序是看不出所以然的。
[解决办法]
float A,B;
A=rand7();
B=(A/2.0+0.5)+(A-1);//B的取值是在1~10,
[解决办法]
这题主要考的是对概率的理解。程序关键是要算出rand10,1到10,十个数字出现的考虑都为10%.根据排列组合,连续算两次rand7出现的组合数是7*7=49,这49种组合每一种出现考虑是相同的。怎么从49平均概率的转换为1到10呢?我想到的方法是:
1.rand7执行两次,出来的数为a1.a2.
2.如果a1*7+a2<40,b=(a1*7+a2)/4+1,
如果a1*7*a2>=40,重复第一步
[解决办法]
探讨
float A,B;
A=rand7();
B=(A/2.0+0.5)+(A-1);//B的取值是在1~10,

热点排行