![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
Merovingean |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.7.2015 Репутация: нет Всего: нет |
Добрый вечер.
Столкнулся с проблемой. Вроде и знаю как решить, но не слишком красиво получается. Вопрос такой: Дано N файлов общим размером более 100 мегабайт. В файлах находятся отсортированные номера. Например, семи- или восьмизначные. Номера разделены между собой пробелами. Нужно слить все файлы в один. Внутри файла-результата номера тоже должны быть отсортированы. При этом, нежелательно использовать оперативной памяти более 20-30 мегабайт. Подскажите пожалуйста, как это покрасивее реализовать? Сам я пока не придумал ничего лучше, чем брать по одному из каждого файла, искать наименьший и совать его в выходной или сливать вместе попарно. Ну и вариации этих подходов. |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
А что здесь некрасивого? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Merovingean |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.7.2015 Репутация: нет Всего: нет |
Возможно, паранойя. Опыта мало. ![]() Тогда уточню. Ну вот скажем файлов оказалось 500 или 2000 или больше. Предполагается, что открываются все файлы сразу и из каждого файла берется первый номер, в полученном массиве ищется меньший и кладется в выходной. Место найденного меньшего занимает следующий номер из того же файла, что и найденный меньший. Это хороший вариант? В плане производительности. Это сообщение отредактировал(а) Merovingean - 8.7.2015, 22:50 |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
||||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Это хороший вариант. В плане производительности - это весьма нелёгкий вопрос. Некогда я развлекался созданием поисковой системы, в которой проиндексированные слова и связанные с ними записи хранились в особом файле, собиравшемся по-новой при переиндексации. На определённом этапе возникла задача объединения двух таких файлов в один, и была написана программа, которая могла объединять всего два файла в один. Спустя некоторое время я переписал программу объединения, чтобы она могла обрабатывать сразу несколько файлов. Но увы, народ, работавший с предыдущей версией, пожаловался, что новая версия объединяла сразу несколько файлов значительно медленнее (в несколько раз), чем последовательное попарное слияние файлов. В чем там было дело, я не успел разобраться, но такой факт имел место быть. Возможно, Вам не нужно на каждом этапе искать (среди имеющихся 1...500-2000 номеров) наименьший номер (это как раз потеря производительности), Вам нужно хранить уже считанные (но несброшенные в окончательный файл из-за их ненаименьшести) из файлов номера в отсортированном списке. Когда Вы сбрасываете наименьший из номеров (который при отсортированности списка легко определяется), то вместо него (если файл ещё не закончился) Вы в список добавляете следующий номер из этого же файла, но не на старое место, а согласно сортировке. Если файл закончился, то он как бы выпадает из этого списка, уменьшая размер списка. Возможно, и это все ерунда, а попарное слияние самое быстрое. Не знаю. Нужно ставить эксперименты, нужно анализировать, считать количество сравнений и т.д. И ещё, просто одновременная работа с тысячей файлов (вне зависимости от сравнений) может сильно подтормаживать. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Merovingean |
|
||||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.7.2015 Репутация: нет Всего: нет |
Вопрос решил примерно следующим образом:
Это сообщение отредактировал(а) Merovingean - 28.7.2015, 08:47 |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Merovingean, красиво же)))
PS А вдруг пустой input-файл попадётся? Добавлено через 4 минуты и 23 секунды Туплю, но почему second'ы сравниваются? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Merovingean |
|
|||
Новичок Профиль Группа: Участник Сообщений: 4 Регистрация: 8.7.2015 Репутация: нет Всего: нет |
Поправил. Писал на память и упустил пару моментов. В моем случае все немного сложнее и вместо номеров UUID. Но смысл не меняется. Куда более серьезная проблема в том, что код не универсален - система не даст открыть любое количество файлов. |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Это не большая проблема - сливайте по несколько файлов зараз (сколько даст открыть система), потом сливайте файлы результаты от первого шага. Если их будет слишком много - опять делите на пачки и сливаете. Получается дерево слияния файлов. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |