Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.10.2013, 17:09   #1
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию Удалить дубликаты строк

Дано 2 текстовых файла. Общий размер этих файлов, допустим, влазит в оперативку (не больше 3 Gb). Нужно удалить из второго файла все строки, которые уже есть в первом файле. Язык - free pascal.

Вопрос первый и главный: как хранить данные в памяти? Сначала попробовал "в лоб" в дельфях TStringList и LoadFromFile - 28 Mb текстовый файл грузил примерно минут 5-6. Этот вариант отпал сразу. Далее попробовал описать массив так:
Код:
Type
  SType = Array [0..MaxLongInt div 81-1] of String[80];
  pStr = ^SType;
Тут же столкнулся с 2мя проблемами: 1) для того, что бы выделить необходимое кол-во памяти, нужно знать кол-во строк в файле - приходится сначала прочитать файл и посчитать кол-во строк, а затем еще раз прочитать файл уже в массив. Два раза читаем один и тот же файл. 2) Неэкономный расход памяти - для каждой строки используется 81 байт, даже если строка из 3-ех символов. Если первая проблема не такая уж проблема, то вот чрезмерный перерасход памяти - проблема.

Дальше сделал просто массив байт:
Код:
Type
  BufferType    = Array[0..MaxLongInt-1] of Byte;
  pBuffer       = ^BufferType;
Туда строки попадают в обычном виде - нулевой байт - размер, дальше строка, сразу за ней размер следующей строки и следующая строка и тд.
Все хорошо с памятью, но проблема с сортировкой такого массива - индексов же нет, что бы вычислить нужный элемент нужно пробегать с самого начала массива по размерам строк. Это медленно.

Пока сделал без сортировки, но работает адски медленно в сравнении с аналогами..
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 05.10.2013, 17:41   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

А вариант загрузить в базу какой-либо СУБД и запросом сделать что нужно не катит?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 05.10.2013, 17:46   #3
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
А вариант загрузить в базу какой-либо СУБД и запросом сделать что нужно не катит?
Ну это по по муравью из танка получится. Тут утилитка то по идее на пару килобайт должна быть.
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 05.10.2013, 17:52   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
Ну это по по муравью из танка получится
Ничего подобного. В тот же ACCESS загрузить и пусть запрос сам находит дубликаты, индексы не забыть сделать для скорости
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 05.10.2013, 18:51   #5
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,777
По умолчанию

Цитата:
Сообщение от Tronix Посмотреть сообщение
Дано 2 текстовых файла. Общий размер этих файлов, допустим, влазит в оперативку (не больше 3 Gb). Нужно удалить из второго файла все строки, которые уже есть в первом файле.
Если это требуется решить алгоритмически в программе, я бы сделал так:
  • Проходим по первому файлу, читаем последовательно строки.
  • Строки не сохраняем, вместо этого сохраняем их хеш.
  • Проходим по второму файлу, читаем последовательно строки, считаем хеш.
  • Ищем хеш, если не находим, сохраняем строку.
Если для хранения хешей использовать подходящий контейнер -- скажем, двоичное дерево или хотя бы отсортированный массив, получится очень быстро.
Vapaamies на форуме Ответить с цитированием
Старый 05.10.2013, 18:55   #6
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
Если это требуется решить алгоритмически в программе, я бы сделал так:
  • Проходим по первому файлу, читаем последовательно строки.
  • Строки не сохраняем, вместо этого сохраняем их хеш.
  • Проходим по второму файлу, читаем последовательно строки, считаем хеш.
  • Ищем хеш, если не находим, сохраняем строку.
Если для хранения хешей использовать подходящий контейнер -- скажем, двоичное дерево или хотя бы отсортированный массив, получится очень быстро.
Я тоже об этом думал, но я мало чо смыслю в криптографии и меня мучает вопрос - а не будет ли иногда коллизий, то есть когда хеши у двух разных строк оказываются одинаковыми? Какую хеш-функцию лучше всего использовать.?

Не понял насчет сортированного массива - чего сортировать, хеши? Это же бессмыслица имхо?
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 05.10.2013, 19:07   #7
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,777
По умолчанию

Цитата:
Сообщение от Tronix Посмотреть сообщение
Это же бессмыслица имхо?
То есть, поиск хеша в наборе должен происходить по волшебству простым перебором, а не методом деления надвое?
Vapaamies на форуме Ответить с цитированием
Старый 05.10.2013, 19:13   #8
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Цитата:
Сообщение от Vapaamies Посмотреть сообщение
То есть, поиск хеша в наборе должен происходить по волшебству простым перебором, а не методом деления надвое?
Ну это же поиск, а не сортировка. Да, искать хеш наверное лучше методом деления пополам.
Дык какую хеш-функцию заюзать? Наверное будет лучше, если результат работы хеш-функции будет в виде Int32, или если этого недостаточно, то в Int64, чтоб был массив простых чисел. Отсюда следует, что MD5 вряд-ли подходит, ибо на выходе оно выдает строку типа 'a3f5dedf87ad78d789d56d5', что не лезет в регистр процессора никак за раз.
Но вопрос по прежнему с уникальностью - хватит ли Int32 (int64) для того, что бы не было коллизий?
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 06.10.2013, 16:03   #9
Tronix
Форумчанин
 
Аватар для Tronix
 
Регистрация: 15.06.2010
Сообщений: 740
По умолчанию

Не, все это байда - хеши фигеши. Нужно полюбому сортировать первый файл и только потом искать
Чтобы понять рекурсию, сперва нужно понять рекурсию.
Tronix вне форума Ответить с цитированием
Старый 06.10.2013, 16:26   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Tronix Посмотреть сообщение
Не, все это байда - хеши фигеши. Нужно полюбому сортировать первый файл и только потом искать
не, не байда. Иногда - очень полезная штука!!

И в данном случае лучше брать не крипографический хеш, а какой-нибудь быстрый (CRC). для избавления от возможных коллизий, можно его (хеш) чуть улучшить. Например, добавить в начало хеша длину строки.
А сортировать нужно как раз по хешу. И его использовать для поиска совпадения.

Впрочем, мне почему то кажется, что Вы уже для себя всё решили!

Последний раз редактировалось Serge_Bliznykov; 06.10.2013 в 16:29.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Удалить дубликаты из разных книг (листов) mojo Microsoft Office Excel 2 04.08.2012 13:28
удалить много строк из listbox delphi SonicBob Помощь студентам 3 19.09.2011 10:46
удалить дубликаты в stringlist yuran111 Общие вопросы Delphi 3 29.04.2011 18:24
Удалить повторы строк Federal Помощь студентам 16 27.02.2011 02:37
Как в удалить кучу строк, через одну? levohotnik Microsoft Office Excel 6 09.09.2010 21:08