随机读取一行,O(N)

Posted 大道至简

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了随机读取一行,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;

以上是关于随机读取一行,O(N)的主要内容,如果未能解决你的问题,请参考以下文章

数组和链表的区别

Java I/O---RandomAccessFile类(随机访问文件的读取和写入)

shell怎样随机读写遍历文件中指定分隔符的记录

用于随机读取的 mmap 与 O_DIRECT(涉及哪些缓冲区?)

JAVA如何随机读取记事本中的某一行

单链表与顺序表的对比