C++ 从C+;中的文本文件中随机选取一行+;

C++ 从C+;中的文本文件中随机选取一行+;,c++,file,random-sample,C++,File,Random Sample,我试图从文本文件中随机读取一行 到目前为止,我的代码选择第一行,但我需要一个随机行 我怎样才能得到一条随机线 string line; if(infile.good()){ getline(infile, line); } 您可以将文件的行读入std::vector,并随机访问向量大小范围内的特定行: std::string line; std::vector<std::string> lines; while(getline(infile, line)) { li

我试图从文本文件中随机读取一行

到目前为止,我的代码选择第一行,但我需要一个随机行

我怎样才能得到一条随机线

string line;
if(infile.good()){
    getline(infile, line);
}

您可以将文件的行读入
std::vector
,并随机访问向量大小范围内的特定行:

std::string line;
std::vector<std::string> lines;
while(getline(infile, line)) {
    lines.push_back(line);
}

if(lines.size() >= 4) {
     std::cout << "Line number 5: " << lines[4] << std::endl;
}
std::字符串行;
std::矢量线;
while(getline(infle,line)){
线。推回(线);
}
如果(lines.size()>=4){

std::cout调用
getline
随机次数,并确保在到达文件末尾时停止循环


只要您不知道文件中的行有多长,就无法计算任何行的开头(当然,第一行除外)然后直接搜索到该点。

您可以将行起始的文件偏移量存储到
std::vector
中。接下来,生成随机数。将该数字用作
std::vector
的索引,并获取行的起始位置。搜索到该位置并获取行

std::vector<std::streampos> line_offsets;
line_offsets.push_back(0); // The first line.
std::string text_line;
while (getline(text_file, text_line))
{
  std::streampos file_offset = text_file.tellg();
  line_offsets.push_back(file_offset);
}
//...
std::streampos offset = line_offsets[Get_Random_Line_Number()];
text_file.seekg(offset);
std::string random_text_line;
getline(text_file, random_text_line);
std::矢量线偏移量;
线偏移。向后推(0);//第一行。
std::字符串文本_行;
while(getline(文本文件,文本行))
{
std::streampos file_offset=text_file.tellg();
行偏移量。向后推(文件偏移量);
}
//...
std::streampos offset=line_offset[Get_Random_line_Number()];
文本文件。参见千克(偏移量);
std::字符串随机\u文本\u行;
getline(文本文件、随机文本行);
这种方法使用的内存不如将每一行文本存储到一个向量中。

您可以使用这些相关文章中描述的“库采样”方法:

正如我们从维基百科关于水库采样的文章中了解到的:

水库采样是一系列随机算法,用于从包含n个项目的列表S中随机选择k个项目的样本,其中n是一个非常大或未知的数字。通常,n足够大,以至于该列表无法放入主内存

使用这种算法,可以在一次传递中从一系列未知长度中选取随机元素,而无需将所有元素存储在内存中

下面是一个(未经测试的)示例:

#包括
#包括
#包括
#包括
int main(){
std::随机_设备种子;
标准:mt19937 prng(seed());
std::字符串行,结果;
对于(std::size\u t n=0;std::getline(std::cin,line);n++){
标准:均匀分布区(0,n);
如果(距离(prng)<1)
结果=直线;
}

std::cout什么是随机性?基于随机数生成器结果的任意行号?我掷了一个骰子,出现了一个1。看起来你的代码还可以。找出如何获得特定k的第k行。添加随机性。获得一个随机数并将其存储在
x
中。读取
x-1
行。然后重新读取下一行d将是您使用的一个。可能的重复:好吧,第一个将得到一个特定的行,它不会得到一个随机的。@Solarmo您可以将
lineno
设置为一个随机数。什么是get\u random\u line\u number()?这是一个您编写以返回随机行号的函数。
std::vector<std::streampos> line_offsets;
line_offsets.push_back(0); // The first line.
std::string text_line;
while (getline(text_file, text_line))
{
  std::streampos file_offset = text_file.tellg();
  line_offsets.push_back(file_offset);
}
//...
std::streampos offset = line_offsets[Get_Random_Line_Number()];
text_file.seekg(offset);
std::string random_text_line;
getline(text_file, random_text_line);
#include <cstdlib>
#include <iostream>
#include <random>
#include <string>
int main() {
    std::random_device seed;
    std::mt19937 prng(seed());
    std::string line, result;
    for(std::size_t n = 0; std::getline(std::cin, line); n++) {
        std::uniform_int_distribution<> dist(0, n);
        if (dist(prng) < 1)
            result = line;
    }
    std::cout << "random line: '" << result << "'\n";
}
$ g++ test.cc -std=c++11 && ./a.out < test.cc
random line: '#include <iostream>'