C++:从文本文件中读取随机行

3

我试图编写一个程序,从一个包含50行的文本文件中随机挑选3行并输出到屏幕。

这是我的当前代码:

string line;
int random = 0;
int numOfLines = 0;
ifstream File("file.txt");

    srand(time(0));
    random = rand() % 50;

while(getline(File, line))
{
    ++numOfLines;

    if(numOfLines == random)
    {
        cout << line;
    }

}

我可以让它打印一行随机文字,就像上面那样,但是无法打印三行随机文字。

2
你可以将所有行读入内存(数组或向量)。然后从数组/向量中选择三个“随机”行。 - Martin York
3
你可以在开始时选择3个随机数(确保它们不相同)。然后你的测试是:if (numOfLines == random1 || numOfLines == random2 || numOfLines == random3) - Martin York
@Loki Astari 谢谢!我会尝试弄清楚如何实现第一种选项的!我甚至没有想过用那种方式。 - user5991813
4个回答

3
您需要根据“随机”所指的具体含义、您想要的输出类型以及输入内容来决定应该采取哪种方法。例如,如果您想要选择任意三行且所有行都有相等的机会成为输出行,同时您了解行数,那么可以采用以下方法:
  int number_of_lines = 50;

  // a vector to hold all the indices: 0 to number_of_lines
  std::vector<int> line_indices(number_of_lines);
  std::iota(begin(line_indices), end(line_indices), 0); // init line_indices

  // C++11 random library (should be preferred over rand()/srand())
  std::random_device r;
  std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
  std::mt19937 eng(seed);

  // shuffle the line_indices:
  std::shuffle(begin(line_indices), end(line_indices), eng);

  int number_of_lines_to_select = 3;
  assert(number_of_lines_to_select <= number_of_lines);

  std::string line;
  std::ifstream file("file.txt");

  int line_number = 0;
  while (std::getline(file, line)) {
    for (int i = 0; i < number_of_lines_to_select; ++i) {
      if (line_number == line_indices[i]) {
        std::cout << line << '\n';
      }
    }
    ++line_number;
  }

实时示例

(或者您可以将整个文件读入字符串向量中,对该向量进行洗牌,并直接选择前三个,而不是间接使用索引数组。)

如果您想选择三行随机文本,并且希望每行有被选两次或三次的机会,则可以像KaiEn Suizai的第二个示例那样做。

另一个选择不依赖于知道行数:使用算法R进行水塘抽样。使用此方法,您可以通过某个公式的概率挑选出文件中的行。在最后,您将得到所需数量的行并将其打印出来。示例


0

每次获取一个随机数后,您需要获取一个新的随机数。这种方法需要在文件上进行3次循环。

int count = 1;
While(count <= 3)
{
    random = rand() % 50;
    while(getline(File, line))
    {
        ++numOfLines;

        if(numOfLines == random)
        {
            cout << line;
        }
    }
    count++;
}

如果你得到了三个随机数,那么就开始 while 循环。

random = rand() % 50;
random1 = rand() % 50;
random2 = rand() % 50;
while(getline(File, line))
{
    ++numOfLines;

    if(numOfLines == random || numOFLines == random1 || numOfLines == random2)
    {
        cout << line;
    }
}

0
#include <iostream>
#include <fstream>
#include <random>
#include <string>
#include <vector>

int randomNumber() { // Using C++11 random features
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution<double> dist(0.0, 50.0);
    return dist(mt);
}

int main()
{
    std::ifstream file("file.txt");
    std::vector<std::string> lines(50); // # of lines here (instead of using push_back)

    while (file.is_open()) {
        for (auto i = 0; i < lines.size(); ++i) {
            std::getline(file, lines[i]);
        }
        file.close();
    }

    std::vector<int> rand_index(3); // # of random numbers here

    for (auto i = 0; i < rand_index.size(); ++i) {
        rand_index[i] = randomNumber();
    }

}

0
//first store the line numbers you want to read in array, you can do it as follow:

int linetoRead[3];

for(int i =0 ;i<3;i++)
{
    linetoRead[i] =  rand() % 50;
}

bool isKeep(int lineN)
{
    for(int i =0 ;i<3;i++)
    {
    if(linetoRead[i] == lineN)
        return true;
    }
    return false;
}
//then do the while loop as follows
int LineRead = 0;
int lineN = 0;
while(getline(File, line) && LineRead < 3)
{
    if(isKeep(lineN))
    {
        // keep the line or display it
        LineRead++;
        cout << line;
    }
    lineN++;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接