随机读取一行,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;
}
posted @ 2023-03-16 19:49  ecnu_lxz  阅读(19)  评论(0编辑  收藏  举报