Случается такое когда у вас есть определенный список строк и вам надо удалить из него все дубликаты, т.е. все повторяющиеся слова (строки). Это может быть список каких-нибудь паролей или IP адресов, Email ящиков, сайтов или чего нибудь еще. Не важно, что там, главное то, что задача остается неизменной и дубликаты необходимо удалить любой ценой. Понятное дело, что при работе с большими объемами данных удалять дубликаты вручную просто не мыслимо и надо как то автоматизировать этот процесс.
Как правило в функционал стандартных программ для работы с текстом подобные функции не заложены и это несколько усложняет реализацию решения, но, к счастью, не все так плохо и методы для автоматизации данного процесса уже давно имеются. Об этом далее.
Удалить дубликаты строк из списка
Если у вас есть текстовый документ со списком строк и вам надо удалить дубликаты этих строк то можно воспользоваться, всем знакомой, программой MS Excel.
Готовые программы для удаления дубликатов слов
Для экселя, идете в пункт данные-расширенный фильтр-выделяете ваш список, копировать результат в другое место, галочку около уникальные записи. Еще, в подобных случаях, можно поступить так: Копируем в Excel, потом данные-сортировка, в соседнем столбце формула =ЕСЛИ(А3=А2;»*»;» «) появятся звёздочки везде где есть повторения. Далее накладываем авто фильтр на оба столбца и удаляем строки со звёздочками. Остается, если нужно, вернуть очищенный список в текстовый редактор.
На ряду с этим можно просто вставить весь текст в программу Excel, если все слова записаны в столбик — то при копировании в ексель они попадут в ращные строки в одном столбце. Надо будет выделить этот столбец, перейти на вкладку инструментов «Данные» и воспользоваться инструментом «Удалить дубликаты». После этого, на всякий случай, можно еще воспользоваться функцией удаления лишних пробелов =СЖПРОБЕЛЫ().
Так же пользуйтесь сторонним софтом для подобных целей т.к. в стандартных программных продуктах для работы с текстом такие функции, как правило, не включены. Такие программы как: DupKill, Text Duplicate Killer с легкостью сделают подобную работу.
Своя реализация в программном коде
Как вы понимаете готовыми программами все не ограничивается и при желании, и определенного багажа знаний, можно саморучно написать скрипт для подобных целей, ведь это весьма простая задача, которая не должна вызвать затруднений даже у новичка программиста.
Ниже приведены различные куски программного кода на разных языках программирования, которые реализуют решения поставленной задачи.
PHP код
[php]
<?php
$a = file(‘text.txt’);
$a = array_unique($a);
$h = fopen(‘text.txt’, ‘w’);
fwrite($h, implode("\r\n",$a));
fclose($h);
?>[/php]
Код на Pascal
[pascal]
var s:array[1..1000] of string;
i,k:integer;
st:string;
f,g:text;
begin
assign(f,’C:\v\er.txt’); \\ тут укажи путь к файлу
reset(f);
while not eof(f) do begin
readln(f,st);
k:=k+1;
s[ k ]:=st;
end;
for i:=1 to k do
writeln(s[ i ]);
assign(g,’C:\v\er1.txt’); \\ тут укажи путь к новому файлу
rewrite(g);
for i:=1 to k do
if s[ i ] <> s[i+1] then writeln(g,s[ i ]);
close(f);
close(g);
end.[/pascal]
Тоже на Delphi
[delphi]
procedure TForm1.Button1Click(Sender: TObject);
var
FLoad, FSave: TStringList;
i: integer;
tmp: string;
begin
FLoad := TStringList.Create;
try
FSave := TStringList.Create;
try
FLoad.LoadFromFile(‘file1.txt’);
for i := 0 to FLoad.Count — 1 do
begin
tmp := FLoad[i];
if FSave.IndexOf(tmp) = -1 then
FSave.Add(tmp);
end;
FSave.SaveToFile(‘file2.txt’);
finally
FSave.Free;
end;
finally
FLoad.Free;
end;
end;
[/delphi]
Другая реализация на Delphi
[delphi]
var
sl: TStringList;
begin
sl := TStringList.Create;
sl.Duplicates := dupIgnore;
sl.sorted := true;
sl.AddStrings(Memo1.Lines);
Memo1.Lines := sl;
sl.Free;
end;
[/delphi]
Еще код на Delphi
[delphi]
var i,j:integer;
t: TStringList;
begin
t:=TStringList.Create;
t.AddStrings(memo.lines);
t.Sort;
memo.Clear;
memo.Lines.AddStrings(t);
t.Free;
for i:=0 to memo.Lines.Count-1 do
for j:=i+1 to memo.Lines.Count-1 do
if memo.Lines[j]=memo.Lines[i] then
while memo.Lines[j]=memo.Lines[j-1] do begin
memo.Lines.Delete(j);
memo.Lines.Delete(j-1);
end;
end;
[/delphi]
Более оптимизированный вариант кода Delphi
[delphi]
var
sl: TStringList;
i, j: integer;
str: string;
begin
sl := TStringList.Create;
sl.AddStrings(Memo1.Lines);
for i := 0 to Memo1.Lines.Count — 1 do
begin
str := Memo1.Lines[i];
if str = » then continue;
sl.Strings[i] := »;
if sl.IndexOf(str) <> -1 then
begin
sl.Text := StringReplace(sl.Text, str, », [rfReplaceAll]);
Memo1.Text := StringReplace(Memo1.Text, str, », [rfReplaceAll]);
end
else sl.Strings[i] := str;
end;
for i := sl.Count — 1 downto 0 do
if sl.Strings[i] = » then sl.Delete(i);
Memo1.Lines := sl;
sl.Free;
end;
[/delphi]
Думаю приводить еще множество кода будет уже лишним, т.к. все, при желании, можно отыскать в интернете да и то, что тут представлено вполне решает поставленную задачу. Спасибо за внимание, надеюсь удаление одинаковых строк у вас не заняло много времени.