Для следующей проблемы, пожалуйста, предложите лучшее решение (с точки зрения сложности времени). Мой подход я объяснил в последний раз.
Есть файл с записями в следующем формате: - RecordType; Symbol; цена; id; parentId
Пример файла выглядит как -
RecordType;Symbol;price;id;parentId
- A;BANK_X;20;2345;0
- A;BANK_Y;30;2346;0
- A;BANK_Z;40;2347;0
- M;BANK_X;50;2348;2345
- M;BANK_Y;10;2349;2346
- A;BANK_X;20;2350;0
- A;BANK_E;40;2351;0
- M;BANK_X;45;2352;2345
- M;BANK_X;20;2353;2350
Такой файл содержит миллионы записей. Цель состоит в том, чтобы написать эффективную программу на C ++, чтобы разбить файл на несколько файлов таким образом, чтобы каждый файл меньшего размера содержал Y записей, где Y - целое число, указанное в качестве входных данных.
Указания, которые следует запомнить:
- Каждая запись имеет уникальный идентификатор (т. Е. Второе последнее поле в записи)
- Для символов, соответствующих A и M, записи должны находиться в одном и том же меньшем файле.
ДляНапример, если файл примера разбит на файлы, содержащие минимум 2 строки, то в одном файле должны быть следующие записи:
- A;BANK_X;20;2345;0
- M;BANK_X;50;2348;2345
- M;BANK_X;45;2352;2345
Мой подход к решению проблемы:
Используемая структура данных:
- Очередь: в ней будут объекты, ключом которых будет id (это родители), а значением в объекте будет вектор, в котором будет список дочерних элементов.
- Unordered_map 1: Key: id (т.е. идентификаторы, чья запись имеет значение 0 в последнем поле), value: string (т.е. запись этого идентификатора считывается из файла)
- Unordered_map 2: Key: id (т.е. идентификаторычья запись не имеет0 значение в последнем поле), значение: строка (то есть запись этого идентификатора, считанная из файла)
Алгоритм:
- Чтение строки файлапо строке
- Анализировать последние 2 поля записи
- Проверить, является ли id родительским (то есть, если последнее поле записи равно 0). Если YES: создать объект {id, vactor } и вставитьочередь Добавить идентификатор и строковую запись в unordered_map 1 Если НЕТ: Найти родительский идентификатор в очереди и добавить дочерний идентификатор в векторе (Это можно сделать при поиске с постоянным временем) Добавить идентификатор и строковую запись в unordered_map 2
- Выполнитьописанные выше шаги до конца файла.
- Теперь начните добавлять очередь в очередь и для каждого идентификатора (который является родительским) получить строку записи из Unordered_map 1, записать в новый файл, также для его дочерних элементов (которые доступны в векторе) получить строку записи из Unordered_map 2 записать в файл. Здесь я проверю минимальные строки.
- На основе значения Y получите запись для идентификаторов (parent) и потомков из unsorted_map и запишите в новые файлы.
Если я рассмотрю образец файла, упомянутый в утверждении, после применения моих структур данных algo будут следующие значения: -
Queue< int, std::vector < int> >: [ {2345, <2348, 2352>}, {2346, <2349>}, {2347, <empty>}, {2350, <2353>}, {2351, <empty>}]
Unordered_map 1 < int, std::string >: [{2345, "A;BANK_X;20;2345;0"}, {2346, "A;BANK_Y;30;2346;0"}, {2347, "A;BANK_Z;40;2347;0"}, {2350, "A;BANK_X;20;2350;0"}, {2351, "A;BANK_E;40;2351;0"}]
Unordered_map 2 < int, std::string >: [{2348, "M;BANK_X;50;2348;2345"}, {2349, "M;BANK_Y;10;2349;2346"}, {2352, "M;BANK_X;45;2352;2345"}, {2353, "M;BANK_X;20;2353;2350"}]