• Главная
  • Исходники Delphi
  • Справочники Delphi
  • Книги Delphi
  • Основы Delphi
  • библиотека Delphi исходников
  • Форум
  • Блоги

Последние записи

  • Прозрачность тайлсета в TPNGImage
  • Как сделать VBA макрос в excel
  • Поиск по столбцу 1-ого не нулевого значения (формулой в Microsoft Office Excel)
  • Простановка единиц в ячейки под объектами (Microsoft Office Excel)
  • Расчет затраченного времени между определенным рабочим временем (формулой в Microsoft Office Excel)
  • Мигающий экран на Assembler
  • VBA-макрос по копированию 10 строчек в выбранном диапазоне в Microsoft Office Excel
  • Копирование только нужного диапазона в Microsoft Office Excel
  • Перенос диапазона стоки в Microsoft Office Excel на другой лист по условию
  • Мелодия в Pascal.ABC.Net с помощью System.Console.Beep — задержка воспроизведения звука

made in programmersforum 1

programmersforum1

  • .NET
  • ASP.NET
  • assembler
  • Basic
  • c/c++
  • CMS
  • Delphi
  • HTML
  • iPhone
  • Java
  • JavaScript
  • Linux
  • Pascal
  • Perl
  • Photoshop
  • php
  • Python
  • Ruby
  • SEO
  • sql
  • VBA
  • Win Api
  • Windows
  • XML и XSLT
  • Администрирование ОС
  • Апгрейды
  • Архив
  • Безопасность
  • Блоги
  • Веб-аналитика
  • Железо
  • Журнал
  • Заметки
  • Имейдж
  • Интервью
  • Исходники
  • Новости
  • Общалка
  • Операционные системы
  • Пост-обзор
  • Профлитература
  • Рассылка
  • Реклама
  • си шарп
  • Советы
  • Софт
  • Статьи
  • Топик-обзор
  • Файлы








26th
Сен

Сравнение текстовых файлов \ Варианты

Posted by obzor under Delphi

Строки текстового файла 1.txt необходимо проверить на совпадение — со строками текстового файла 2.txt. И уникальные строки, которых нет в файле 1.txt, записать в файл 3.txt.

К примеру:

Tекст в первом файле — 1.txt
Test1
Test2
Test3
Test4
Test5

Текст во втором файле — 2.txt
Test1
Test2
Test3
Test4
Test5
Stroka1
Stroka2
stroka3

После сравнения, результат в третьем файле — 3.txt
Stroka1
Stroka2
stroka3

Вот мои решения и их недостатки =>

Вариант №1 (Загрузка в память):

Код:

 
var
  i: integer;
  s1, s2: TStrings;
begin
  s1 := TStringList.Create;
  s2 := TStringList.Create;
  Try
    s1.LoadFromFile('1.txt');
    s2.LoadFromFile('2.txt');
    for i := s1.Count - 1 downto 0 do
      if s2.IndexOf(s1) >= 0 Then
        s1.Delete(i);
    s1.SaveToFile('3.txt');
  Finally
    s1.Free;
    s2.Free;
  End;
end;

Проблема в следующем: Если файл размеров 500 мегабайт то вся память забивается и выскакивает ошибка — Out of memory. Ну это само собой понятно поскольку я загружаю и обрабатываю все в памяти.

Вопрос: Может как то можно оптимизировать код в этом варианте, кто что может подсказать ?

Вариант №2 (Чтение построчно):

Код:

var
  f1, f2, f3: textfile;
  s1, s2: string;
  b: boolean;
begin
  assignfile(f1,  '1.txt');
  assignfile(f2,  '2.txt');
  assignfile(f3, '3.txt');
  rewrite(f3);
  reset(f1);
  while not eof(f1) do
  begin
    readln(f1, s1);
    reset(f2);
    b := true;
    while not eof(f2) and b do
    begin
      readln(f2, s2);
      if s2 = s1 then
        b := false;
    end;
    if b then
      writeln(f3, s1);
  end;
  closefile(f1);
  closefile(f2);
  closefile(f3);
end;

Проблема в следующем: Очень и очень медленно работает, ну и тут принцип понятен:
1.Читаем строку из 1.txt файла
2.Открываем 2.txt, проходим по нему ищем совпадение
3.Закрываем 2.txt файл
И так для каждой строки из первого файла. Это куча времени и затрат.

Вопрос, скорее всего утверждение: В этом варианте, само собой понятно что далеко не уедешь.

П.С: Подскажите еще варианты, при использования которых, можно обрабатывать файлы до 1 гигабайта, не загружая память и при этом, иметь, хотя бы, среднюю скорость обработки ?

evg_m

Вар 1. Out of memory
Не делать S1.Delete(j)
иметь (завести) еще один массив
SetLEngth(mm, s1.Count);
в котором отмечать ОТМЕЧАТЬ(запоминать) строки для последующего удаления
потом s2.Clear(Free)
потом удалить помеченые и сохранить
или же (если удаление снова даст outofmemory) ПОСТРОЧНАЯ запись в файл неотмеченных строк.

вар2.
не читать много-много раз один файл(2.txt) а считать его один раз в StringList и искать ТАМ.

Serge_Bliznykov

я бы тоже начал с этого способа. Если, конечно, файл 2.txt легко помещается в память и размеры файла 1.txt позволяют его обрабатывать построчно (скорость обработки достаточная).

выглядит это так:

Код:

var
  f1, f3: textfile;
  s1 : string;
  ts2: TStrings;
begin
  assignfile(f1, '1.txt');
  assignfile(f3, '3.txt');
  rewrite(f3);
  reset(f1);
  ts2 := TStringList.Create;
  ts2.LoadFromFile('2.txt');

  while not eof(f1) do
  begin
    readln(f1, s1);
    if ts2.IndexOf(s1) < 0 
    then 
      writeln(f3, s1);
  end;
  ts2.Free;
  closefile(f3);
  closefile(f1);
end;

ну, и возможны варианты.
например, если отсортировать файл 2.txt, то можно воспользоваться индексированным поиском (см. метод Find()), который работает исключительно быстро.

тема на форуме

 

Похожие статьи

  • GetHashCode vs Equals
Теги: сравнение | текстовые файлы








© Copyright "Клуб программистов" – материалы по Delphi и С++. Создание и продвижние сайта - Веб-сателлит.