伪随机解决真随机问题

12 篇文章 0 订阅
1 篇文章 0 订阅

1.从文件中随机取一行数据

如果先统计文件有多少行,再根据rand() % 行数选择对应行也是可以行的,但效率显然会有点低了。有没有一种方法可以只遍历文件一次了?请看代码:

[cpp]  view plain copy
  1. //从文件中取机选取一行  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <time.h> 
  5. #include<fstream> 
  6. int main()  
  7. {  
  8.     printf("           从文件中取机选取一行 \n");  
  9.   
  10.     int i, num, nChooseNum;  
  11.     const char strFileName[] = "in.txt";  
  12.       
  13.     fd=ifstream(strFileName);  
  14.     srand(time(NULL));  
  15.     i = 1;  
  16.     string line;
  17.     while (getline(fd,line))  
  18.     {  
  19.         if (rand() % i == 0)  
  20.             nChooseNum = num;  
  21.         i++;  
  22.     }  
  23.     printf("从文件中选取出: %d\n", nChooseNum);  
  24.     return 0;  
  25. }  

假设有三行,

(1)i==1,if()为真的概率为 1

 (2)1==2,if()为真的概率为 1/2

  (3) i==3,if()为真的概率为1/3

所以选择一行的概率,(1)为真,(2),(3)为假概率为1*  1/2  *  2/3   =1/3。选择第一行的概率为1/3

其他行同理均是1/n 的概率。


2.谷歌笔试题:如何随机选取1000个关键字

给定一个数据流,其中包含无穷尽的搜索关键字(比如,人们在谷歌搜索时不断输入的关键字)。如何才能从这个无穷尽的流中随机的选取1000个关键字?

定义长度为1000的数组。

对于数据流中的前1000个关键字,显然都要放到数组中。

对于数据流中的的第n(n>1000)个关键字,我们知道这个关键字被随机选中的概率为 1000/n。所以我们以 1000/n 的概率用这个关键字去替换数组中的随机一个。这样就可以保证所有关键字都以 1000/n的概率被选中。

对于后面的关键字都进行这样的处理,这样我们就可以保证数组中总是保存着1000个随机关键字。


代码

需要考虑的问题
1.n<m,需要释放申请的空间
2.m<0; 
3.n>=m; 使用完空间后,需要释放空间

int* getRandomMLine(unsigned int m)
{
	int *nChoosen=new int[m];
		unsigned int lineNum=0;
	srand((unsigned int )time(0));
	char c;
	while((c=getchar())!='\n') //模拟去读一行
	{
		lineNum++;
		if(lineNum<=m)
		{
			nChoosen[lineNum-1]=lineNum;  //把前M行,拷贝到蓄水池中;
		}
		else if(rand()%lineNum<m)// 以M/N的概率选择一行
		{
			int location=rand()%m;
			nChoosen[location]=lineNum;
		}

	}
	if(lineNum<m)
	{
		delete[] nChoosen;
		return NULL;
	}
	else
	return nChoosen;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值