Выберите случайную строку из текстового файла в переполнении стека

Я пытаюсь прочитать случайную строку из текстового файла.

Мой код до сих пор выбирает первую строку, но мне нужна случайная строка.

Как бы я получить случайную строку?

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

-2

Решение

Вы можете прочитать в строках вашего файла в std::vector<std::string> а также случайным образом получить доступ к определенной строке в диапазоне размеров векторов:

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;
}

Другой вариант — сначала установить случайное число и считать прочитанные строки:

int lineno = 5;
int linecount = 0;
std::string line;
while(getline(infile, line)) {
++linecount;
if(linecount == lineno) {
std::cout << "Line number " << lineno << ": " << line << std::endl;
}
}
2

Другие решения

Вызов getline случайное число раз и обязательно остановите цикл, если вы достигнете конца файла.

Пока вы не знаете, какова длина строк в вашем файле, невозможно каким-либо образом вычислить начало любой строки (кроме самой первой строки, конечно) и искать непосредственно в этой точке.

1

Вы можете использовать подход «Отбор проб резервуаров», как описано в следующих публикациях:

Как мы узнали из статьи в Википедии о взятии проб из резервуара:

Выборка из резервуара — это семейство рандомизированных алгоритмов для случайного выбора выборки из k элементов из списка S, содержащего n элементов, где n — очень большое или неизвестное число. Обычно n достаточно велико, чтобы список не помещался в основную память.

Используя такой алгоритм, можно выбрать случайные элементы из серии неизвестной длины за один проход, без необходимости хранить их все в памяти.

Вот (непроверенный) пример:

#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>'

Для справки:

1

Вы можете сохранить смещения файлов начала строки в 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);

Этот метод не использует столько памяти, сколько сохраняет каждую текстовую строку в векторе.

0
По вопросам рекламы [email protected]