~~淘宝的一道笔试题,大家都说说自己的解法吧~~

southbirdfly 2009-10-26 05:06:19
设计一个算法, 有一亿个会员,要从中随机抽取100万个。
要求(1)不能有重复
(2)在10秒内必须完成。
(3)rand()的范围不大于2的10次方减1
...全文
526 34 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangyilina1987 2011-03-29
  • 打赏
  • 举报
回复
嗯嗯,mark
forster 2009-12-22
  • 打赏
  • 举报
回复
2的10次方减1 能覆盖1亿吧
jstar920 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 xiaoshun123 的回复:]
引用 26 楼 jstar920 的回复:
个人感觉要点是:
1,随机数产生要均匀
2,重复判断要快


1,假设rand()函数产生是等几率的则可以利用它来建立一个均匀的随机数产生器。
10^8 ~=~ 2^26.5
因此可以利用三个9位的二进制数拼接,如下
RAND() = rand(2^9) < <18 + rand(2^9) < <9 + rand(2^9)
如果rand()函数产生是等几率,则可推的R的每一位(共27位)产生0和1都是等几率的。

2,建立一个数组T[100000000]: T[i]=i;
  R[1000000]: T[i]=i;
for(int i=0; i <1000000; i++)
{
  int a = RAND();
  while(1)
  {
    if(T[a]!=-1 && a <=100000000){
      R[i]=a;
      T[a]=-1
      break;
    }
    else
      a = RAND();
  }
}

返回R[1000000]




R[1000000]可以不用,只用T[100000000]是不是就够了?
[/Quote]

那结果保存在哪里呢?如果扫描T[n]=-1的下标的话,平均要扫描10000000/2次,是不是又会降低效率呢?
longlongABB 2009-12-22
  • 打赏
  • 举报
回复
实际上就是用最快的时间完成此题,没什么难度,都是小学生的思维
xiaoshun123 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 jstar920 的回复:]
个人感觉要点是:
1,随机数产生要均匀
2,重复判断要快


1,假设rand()函数产生是等几率的则可以利用它来建立一个均匀的随机数产生器。
10^8 ~=~ 2^26.5
因此可以利用三个9位的二进制数拼接,如下
RAND() = rand(2^9) < <18 + rand(2^9) < <9 + rand(2^9)
如果rand()函数产生是等几率,则可推的R的每一位(共27位)产生0和1都是等几率的。

2,建立一个数组T[100000000]: T[i]=i;
  R[1000000]: T[i]=i;
for(int i=0; i <1000000; i++)
{
  int a = RAND();
  while(1)
  {
    if(T[a]!=-1 && a <=100000000){
      R[i]=a;
      T[a]=-1
      break;
    }
    else
      a = RAND();
  }
}

返回R[1000000]


[/Quote]

R[1000000]可以不用,只用T[100000000]是不是就够了?
jstar920 2009-12-14
  • 打赏
  • 举报
回复
个人感觉要点是:
1,随机数产生要均匀
2,重复判断要快


1,假设rand()函数产生是等几率的则可以利用它来建立一个均匀的随机数产生器。
10^8 ~=~ 2^26.5
因此可以利用三个9位的二进制数拼接,如下
RAND() = rand(2^9)<<18 + rand(2^9)<<9 + rand(2^9)
如果rand()函数产生是等几率,则可推的R的每一位(共27位)产生0和1都是等几率的。

2,建立一个数组T[100000000]: T[i]=i;
R[1000000]: T[i]=i;
for(int i=0; i<1000000; i++)
{
int a = RAND();
while(1)
{
if(T[a]!=-1 && a<=100000000){
R[i]=a;
T[a]=-1
break;
}
else
a = RAND();
}
}

返回R[1000000]

lin0119 2009-12-14
  • 打赏
  • 举报
回复
明白了~高手!
哈哈~
jstar920 2009-12-14
  • 打赏
  • 举报
回复
to 27L
不会有碰撞的的,每次取到一个数a, 就把T[a]赋值为-1,因此下载如果再次取到a时,会判断T[a]是否为-1,如果是会再次取数,直到取到T[a]不为-1为止
lin0119 2009-12-14
  • 打赏
  • 举报
回复
26L:
你返回的R[1000000]数组无法保证不“碰撞”--就是数组中出现两个相同的随机数据。
题目要求不能有重复呢。
lin0119 2009-12-12
  • 打赏
  • 举报
回复
22L的也是高手!

这个大随机数不能通过简单乘法产生。
应该是
(rand()*1000000+rand()*1000+rand())%1000000000
lin0119 2009-12-12
  • 打赏
  • 举报
回复
20L的办法相当不错!
高手!
lin0119 2009-11-29
  • 打赏
  • 举报
回复
1,先产生100万个(0-10^9)的随机数
2,对100万个随机数进行碰撞检查,排除出(100万/10^9)1%约1万个相同的
3,再产生约1万个随机数
4,对约1万个随机数再次碰撞检查
5,重复2-4步骤,直到不再碰撞。

理论上需要运行101.0101万次rand(0-10^9)。
因为限制了rand范围是0-2^10。所以需要运行400万次左右。
这个rand()的时间决定了实现目标的时间。

------以上概率计算好像是错的-----欢迎指正-----
lin0119 2009-11-29
  • 打赏
  • 举报
回复
因为产生随机数的Rand()的实现方法未知,题目中应该给出实现一次rand()需要的时间是多少,才能提出要求10秒的时间限制。
lin0119 2009-11-29
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 wanjiwz 的回复:]
100,000,000里面选1,000,000,把一亿分成100万个大小为100的组,在第1个组里面随机选取一个,然后编号以100递增选出剩下的999,999个,这样不是也能保证每个人的机会均等吗?
[/Quote]
虽然保证了机会均等,但从整体来看,却是平均分布,只能说是伪随机,不符合题目要求。
wanjiwz 2009-11-29
  • 打赏
  • 举报
回复
[Quote=引用楼主 southbirdfly 的回复:]
设计一个算法, 有一亿个会员,要从中随机抽取100万个。
要求(1)不能有重复
    (2)在10秒内必须完成。
    (3)rand()的范围不大于2的10次方减1
[/Quote]

100,000,000里面选1,000,000,把一亿分成100万个大小为100的组,在第1个组里面随机选取一个,然后编号以100递增选出剩下的999,999个,这样不是也能保证每个人的机会均等吗?
小小攻城师 2009-11-29
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 xie0771 的回复:]
在10秒内必须完成。。。。。。

你十秒还是PC十秒?
[/Quote]
楼上不是搞笑的吧 呵呵
晕死
olapla 2009-11-29
  • 打赏
  • 举报
回复
太叽歪了~你们这些人~

告诉你们,1-99999991,a=rnd一次,然后做一次 1-9的循环 a+i

如果能重复,那是他妈的鬼了~而且10秒内绝对完成~

哈哈哈~~

无敌了吧~还有比这更快的?~
zhuxueling 2009-11-29
  • 打赏
  • 举报
回复
20楼犯基本错误,两个随机数相乘,随机性质产生变化的。。

比如,a,b都是1-10之间的随机数,
用a*b,是不可能产生1-100之间的随机数的,比如23这个数就不会产生(素数)。
而且密度也产生了变化,1的概率就明显比25小。
wozuiqiang001 2009-11-29
  • 打赏
  • 举报
回复
20L 的办法不错!
heis07w 2009-11-29
  • 打赏
  • 举报
回复
0-999,0-999,0-99相乘不到100000000吧。这样行不?
while (i<1000000) {
int j = rand()*rand()*rand()%100000000
if (j<i) {
continue;
}
swap(a[i],a[j]);
++i;
}
这样行不?前100万就是了
加载更多回复(14)

15,447

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧