Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Удаление дублирующих строк из файла [D7, XP]


dabreezy ©   (2006-03-13 12:35:00) 

Добрый день.
Кто-нибуть знает как реализовать быстрое удаление дублирующих строк из файла? Я написал процедуру, работает очень медленно, особенно если в файле ~300000 строк:

procedure TForm1.RemoveAllDupl (filename: string);
var
 f: textfile;
 buf,buf2: array of string;
 s: string;
 flag: byte;
 i,i1,i2,i3: Longint;
begin
 assignfile (f,filename);
 reset (f);
 i:=1;
 while not eof(f) do
  begin
    readln (f,s);
    i:=i+1;
  end;
 reset (f);
 SetLength (buf,i+3);
 setlength (buf2,i+3);
 i:=1;
 while not eof(f) do
  begin
    readln (f,buf[i]);
    i:=i+1;
  end;
 closefile(f);
 buf2[1]:=buf[1]; i3:=1;
 for i1:=2 to i-1 do
 begin
   flag:=1;
   for i2:=1 to i3 do
     begin
       if buf2[i2]=buf[i1] then begin flag:=0; break; end;
     end;
   if flag=1 then
     begin
       if buf[i1]<>'' then
       begin
         i3:=i3+1;
         buf2[i3]:=buf[i1];
       end;
     end;
 end;
 assignfile (f,filename);
 rewrite (f);
 for i:=1 to i3 do
  begin
    writeln (f,buf2[i]);
  end;
 flush(f);
 closefile(f);
 setlength (buf,0);
 setlength (buf2,0);
end;


MBo   (2006-03-13 13:54:00) [1]

>работает чуть-чуть быстрее и глючит жутко
Да ну?
У меня на 15М файле код из 1 работает в 40 раз быстрее


dabreezy   (2006-03-13 13:13:00) [2]


> MBo ©   (13.03.06 12:49) [1]
> Если допустима перестановка строк, тогда

Сделал с Tstringlist работает чуть-чуть быстрее и глючит жутко(в файл попадает какая-то белеберда :) Придется оставить старый способ :(


balepa   (2006-03-13 12:51:00) [3]

хотябы так

peremen:= 0;
while not eof(f) do
 begin
   readln (f,s);
   inc(peremen)
 end;

вот это замени
while not eof(f) do
 begin
   readln (f,buf[i]);
   i:=i+1;
 end

на:
for index:= 1 to i do
   Readln(f,buf[index])

вместо i:= i+1 используй inc(i)
уже на пару секунд быстрее :)


dabreezy   (2006-03-13 12:51:00) [4]

Спасибо. Я кстати об этом тоже подумал.:) Единственное надо не забыть List.free; в конце (один раз искал ошибку исчезновения памяти, оказалось что забыл удалить TStringList :)


MBo   (2006-03-13 12:49:00) [5]

Если допустима перестановка строк, тогда проще всего отсортировать, иначе :

procedure TForm2.Button5Click(Sender: TObject);
var
 f,g:TextFile;
 List:TStringList;
 Indx: Integer;
 s:string;
begin
 AssignFile(f,'e:\test.txt');
 AssignFile(g,'e:\test2.txt');
 Reset(f);
 Rewrite(g);
 List:=TStringList.Create;
 List.Sorted:=True;
 while not EOF(f) do begin
   Readln(f,s);
   if not List.Find(s,Indx) then begin
     List.Add(s);
     Writeln(g,s);
   end;
 end;
 Closefile(f);
 CloseFile(g);
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо