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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 29.04.2013, 12:57   #1
megostudent
Форумчанин
 
Регистрация: 31.12.2010
Сообщений: 320
По умолчанию Умное удаление повторов в мемо

В мемо имеется 15 строк такого вида:
Код:
1.1.1.1:1111
1.1.1.1:2222
1.1.1.1:3333
1.1.1.1:4444
1.1.1.1:5555
2.2.2.2:1111
2.2.2.2:2222
2.2.2.2:3333
2.2.2.2:4444
2.2.2.2:5555
3.3.3.3:1111
3.3.3.3:2222
3.3.3.3:3333
3.3.3.3:4444
3.3.3.3:5555
нужно удалить повторы тех строк у которых одинаковое число до знака ":"
в результате должно получиться так:
Код:
1.1.1.1:1111
2.2.2.2:1111
3.3.3.3:1111
ну или любое другое число после ":", главное чтобы числа стоящие до ":" не повторялись.
казалось бы ничего сложного, 2 цикла все решат, но чтот у меня не выходит, вот мой вариант:
Код:
var
i,j:integer;
st,st2:string;
begin
for i:=0 to memo1.Lines.Count-1 do
 begin
  st:=Copy(memo1.lines[i], 1, Pos(':', memo1.lines[i]) - 1);
  //c:=false;
  for j:=0 to memo1.Lines.Count-1 do
    st2:=Copy(memo1.lines[j], 1, Pos(':', memo1.lines[j]) - 1);
    if (st2=st) then
    memo1.Lines.Delete(j);
 end;
end;
megostudent вне форума Ответить с цитированием
Старый 29.04.2013, 13:13   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

во-первых, запомните, прямой цикл FOR НЕ ПОДХОДИТ для тех случаем, когда количество элементов изменяется (в данном случае - уменьшается).
Либо используйте другие виды циклов: while / repeat,
либо, рекомендую, используйте ОБРАТНЫЙ цикл:
Код:
for i:=Count-1 downto 0 do
  if условие then УдалитьСтроку[i];
это раз.
второе. в вашем примере строки отсортированы.
На это можно полагаться при проверке совпадения общей части?!
(если задача допускает, то можно отсортировать строки - это резко упрощает и ускоряет процедуру удаления повторов общей части)

для сортированного списка попробуйте такой код:
Код:
procedure TForm1.Button1Click(Sender: TObject);

  function GetPartBefore(const s : string; FindChar : char) : string;
  begin
    if Pos(FindChar, s)>0 then Result := Copy(s, 1, Pos(FindChar, s)-1)
    else Result := s;
  end;

var
 sPrev : string;
 TS : TStringList;
 i : integer;
begin
  if Memo1.Lines.Count<1 then Exit;
  try
    TS := TStringList.Create;
    TS.Text := Memo1.Lines.Text;

    sPrev := GetPartBefore( TS.Strings[0], ':' );
    i:=1; {начиная со второй строки}
    while i<=(TS.Count-1) do begin
      if sPrev = GetPartBefore( TS.Strings[i], ':' ) then TS.Delete(i)
      else begin
         sPrev := GetPartBefore( TS.Strings[i], ':' );
         inc(i);
      end;
    end;

    Memo1.Lines.Text := TS.Text;
  finally
    FreeAndNil(TS);
  end;
end;

Последний раз редактировалось Serge_Bliznykov; 29.04.2013 в 13:27.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 29.04.2013, 13:55   #3
megostudent
Форумчанин
 
Регистрация: 31.12.2010
Сообщений: 320
По умолчанию

список может быть не сортированый
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
i,j,a,s,q,w:integer;
st,st2,st3:string;
c,d:boolean;
begin
for i:=0 to memo1.lines.Count-1 do
//часть 1 - удаление основных дублей и вывод их в мемо2 с дублями
 begin
  st:=Copy(memo1.lines[i], 1, Pos(':', memo1.lines[i]) - 1);//memo1.lines[i];
  c:=false;
  for j:=0 to memo1.lines.Count-1 do
    st2:= Copy(memo1.lines[j], 1, Pos(':', memo1.lines[j]) - 1);
    if (st2=st) then c:=true;
 if not c then
 begin
  begin
    for a:=0 to Memo1.Lines.Count-1 do
      begin
        if AnsiPos(st, Memo1.Lines[a])<>0 then
          begin
            memo2.Lines.Add(memo1.Lines[a]);
            break;
          end;
      end;
  end;
  begin
    for s:=0 to Memo1.Lines.Count-1 do
      begin
        if AnsiPos(st2, Memo1.Lines[s])<>0 then
          begin
            memo2.Lines.Add(memo1.Lines[s]);
            break;
          end;
      end;
  end;
//часть 2 - удаление дублей 
  for q:=0 to memo2.lines.Count-1 do
   begin
    st3:=memo2.lines[q];
    d:=false;
    for w:=0 to memo3.Lines.Count-1 do
      if (memo3.lines[w]=st3) then c:=true;
   if not c then memo3.Lines.Add(st3);
 end; 
 //memo2.Lines.Add(st);
 //memo2.Lines.Add(st2);
 end;
 end;
end;
работает очень коряво, кидаю больше 3 повторений и сразу работа не та становится.
сейчас проверю код для сортированого списка, если все круто, так какие проблемы отсортировать список до начала удаления дублей)

Последний раз редактировалось megostudent; 29.04.2013 в 13:59.
megostudent вне форума Ответить с цитированием
Старый 29.04.2013, 14:04   #4
megostudent
Форумчанин
 
Регистрация: 31.12.2010
Сообщений: 320
По умолчанию

Работает просто превосходно даже если список не сортированый!
Сергей спасибо большое!
проверял на таком варианте
Код:
2.2.2.2:1111
2.2.2.2:2222
2.2.2.2:3333
2.2.2.2:4444
2.2.2.2:5555
1.1.1.1:1111
1.1.1.1:2222
1.1.1.1:3333
1.1.1.1:4444
1.1.1.1:5555
3.3.3.3:1111
3.3.3.3:2222
3.3.3.3:3333
3.3.3.3:4444
3.3.3.3:5555
результат как и пологается
Код:
2.2.2.2:1111
1.1.1.1:1111
3.3.3.3:1111
megostudent вне форума Ответить с цитированием
Старый 29.04.2013, 14:31   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Работает просто превосходно даже если список не сортированый!
предостерегаю, что данный алгоритм работает так:
Код:
берём левую часть. (до двоеточия)
перебираем записи
  до тех пор, пока левая часть (до двоетоичия) совпадает с запомненной - УДАЛЯЕМ
  иначе, наткнулись на новую группу. Запоминаем левую часть и повторяем цикл.
поэтому.
алгоритм будет прекрасно работать со списком, где СОВПАДАЮЩИЕ левые части идут подряд, друг за другом.
если левые части будут "в разнобой":
1.1.1.1:1111
2.2.2.2:2222
2.2.2.2:5555
1.1.1.1:1111
1.1.1.1:2222
2.2.2.2:7777
1.1.1.1:4444

то такие записи не будут идентифицированы как повторяющиеся и, соответственно, не будут удалены из списка.

Цитата:
спасибо большое!
Большое пожалуйста!
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как в Мемо отменить удаление текста? Andrey770 Общие вопросы Delphi 3 09.04.2012 00:57
Удаление повторов слов в строке as1212 Паскаль, Turbo Pascal, PascalABC.NET 0 08.11.2011 20:55
Удаление повторов с последующим копированием нужной инфы ujen Microsoft Office Excel 4 07.07.2011 01:21
Удаление найденый слов из мемо bulldog5293 Общие вопросы Delphi 0 22.05.2011 15:41
Удаление буквы или пробела в мемо по нажатию на кнопку. troyan32 Общие вопросы Delphi 7 07.02.2011 20:03