1.从文件中随机取一行数据
如果先统计文件有多少行,再根据rand() % 行数选择对应行也是可以行的,但效率显然会有点低了。有没有一种方法可以只遍历文件一次了?请看代码:
- //从文件中取机选取一行
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include<fstream>
- int main()
- {
- printf(" 从文件中取机选取一行 \n");
- int i, num, nChooseNum;
- const char strFileName[] = "in.txt";
- fd=ifstream(strFileName);
- srand(time(NULL));
- i = 1;
- string line;
- while (getline(fd,line))
- {
- if (rand() % i == 0)
- nChooseNum = num;
- i++;
- }
- printf("从文件中选取出: %d\n", nChooseNum);
- return 0;
- }
假设有三行,
(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;
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;
}