Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Сравнение текстовых файлов \ Варианты


Автор: Campus2000 23.9.2018, 16:05
Добрый день, Уважаемые форумчане.

У меня возник такой вопрос: Строки текстового файла 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[i]) >= 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 гигабайта, не загружая память и при этом, иметь, хотя бы, среднюю скорость обработки ?. Заранее благодарен за помощь...

Автор: Romikgy 23.9.2018, 21:53
для ускорения роботы с файлами используйте отображение в память файлов,
для ускорения поиска можно использовать аналоги хеш функций, или сравнивать сначала по первому символу, при совпадении  сравнивать всю строку...
имхо
данная задача и дельфи не совсем совместимы.... почему не воспользоваться допустим базой данных... иль другими языками, которые специально сделать для текстовых обработок?

Автор: _zorn_ 19.10.2018, 16:36
Для ускорения... пинка под зад.
@Romikgy 
Ты издеваешься ? Там же паскаль. Значит школьник или студент.
Какие мапы в память ?

@Campus2000 
Тебе еще пока рано думать о редакторе файлов овер 9000 размера.
Чуть позже познакомишься с маппингом файлов в память. И поймешь что не всегда это добро (когда оперативки маловато).
Вобщем у тебя еще вся жизнь впереди  smile 

Автор: Romikgy 19.10.2018, 19:19
_zorn_, нет , не издеваюсь , а советую то, что посчитал нужным....

PS А вас сударь кажется немного понесло ... вы даже в некоторых постах опускаетесь до мата.... 
так что тормозните слегка...ИМХО
PSS и телепат из вас никакой...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)