随机读取一行,O(N)
从文件中随机读取一行,首先想到的方法是,先确定文件的行数,再确定个在行数范围内的随机数,然后去读取那一行
复杂度是,数一遍行数O(N)+从头读直到读到那一行平均O(0.5N)=O(1.5N)
因为没法直接跳到对应的那一行,还是得从头一行一行数
第二种方法就是本文要记录的方法,看下面的代码,不用数行数,直接开始从头遍历
遍历的过程中,如果随机数(每个循环rand产生的数都不一样)模取当前行数i值为0,即为i的倍数(1/i概率),就让lineData记录该行
如果后续再没有模取i为0的情况,那最终结果就是刚刚上面记录的那一行
如果后续又出现了模取i为0的情况,新行就会覆盖旧行
则,随机取到行i的概率为,随机数模取i为0且后续再无模取为0的情况,即后续不被覆盖:
#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
using namespace std;
string RandLine(const string& fileName )
{
ifstream file(fileName.c_str()) ;
string lineData, readline;
int i = 1 ;
srand((unsigned int)time(NULL)) ;
while (getline(file, readline))
{
if(rand()%i == 0)
lineData = readline;
++ i ;
}
file.close();
return lineData ;
}
int main(int argc, char** argv)
{
cout << RandLine("data.txt") << endl ;
return 0;
}