MiddleКодИногдаЕщё не отвечали
Поток чисел по связанным файлам с бегущим средним и без зацикливания
Файл выдаёт по числу на строку, но строка может вместо этого называть другой файл для перехода. Прочитайте все числа по связанным файлам и после каждого нового числа печатайте бегущее среднее. Ссылки на файлы могут образовывать циклы — никогда не открывайте один файл дважды.
Требования:
- Поддерживайте среднее инкрементально (бегущая сумма и счётчик), не пересуммируя.
- Выявляйте и пропускайте уже посещённые файлы.
void process(const std::string& path) {
// ваш код здесь
}
Допишите реализацию.
Считаем файлы узлами графа, а ссылки — рёбрами; обходим через DFS, держа множество посещённых путей, чтобы цикл не переоткрыл файл. Держим бегущие sum и count; для каждой числовой строки прибавляем её и печатаем sum / count. Ссылка ведёт к названному файлу, только если он не посещён.
- ✗Пересуммировать все числа на каждую строку вместо бегущих суммы и счётчика
- ✗Опускать множество посещённых, из-за чего цикл ссылок зациклится навсегда
- ✗Отслеживать посещения по метке времени или размеру, а не по пути файла
- →Почему множество посещённых превращает это в обычный обход графа?
- →Как держать бегущее среднее численно устойчивым для множества значений?
Оглавление
Задача
Прочитайте числа по связанным файлам, печатая бегущее среднее; не открывайте файл дважды.
Решение
#include <string>
#include <unordered_set>
#include <fstream>
#include <iostream>
static long long sum = 0, count = 0;
static std::unordered_set<std::string> visited;
void process(const std::string& path) {
if (visited.count(path)) return; // цикл: файл уже посещён
visited.insert(path);
std::ifstream in(path);
std::string line;
while (std::getline(in, line)) {
if (!line.empty() && std::isdigit((unsigned char)line[0])) {
sum += std::stoll(line); ++count; // инкрементальное среднее
std::cout << path << ' ' << (double)sum / count << '\n';
} else {
process(line); // строка-ссылка на другой файл
}
}
}
Ключевые моменты
- Файлы — узлы, ссылки — рёбра; обход графа со множеством посещённых.
- Среднее — бегущие
sumиcount, без пересуммирования. - Множество по пути файла завершает циклы ссылок.
Оглавление