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個隨機關鍵字。
代碼
2.m<0;
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;
}