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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.03.2016, 13:00   #1
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
Вопрос Сравнить два TStringList

Есть два TStringList
Код:
  SL1.Add('C:\1.txt');
  SL1.Add('C:\2.txt');
  SL1.Add('C:\3.txt');

  SL2.Add('C:\1.txt');
  SL2.Add('C:\2.txt');
  SL2.Add('C:\3.txt');
  SL2.Add('C:\4.txt');
  SL2.Add('C:\5.txt');
Сравниваем каждую запись SL1 с записями SL2. В итоге нужно вывести
C:\4.txt и C:\5.txt, так как их нет в SL1
Код:
var
  SL3: TStringList;
  I, I2: Integer;
begin
  SL3 := TStringList.Create;
  // Проверка
  for I := 0 to SL1.Count - 1 do
  begin
    for I2 := 0 to SL2.Count - 1 do
    begin
      if not (SL1.Strings[I] = SL2.Strings[I2]) then
      begin
        SL3.Add(SL1.Strings[I]);
      end;
    end;
  end;

  ShowMessage(SL3.Text);
end;
Получаю
C:\1.tx
C:\1.tx
C:\1.tx
C:\1.tx
C:\2.txt
C:\2.txt
C:\2.txt
C:\2.txt
C:\3.txt
C:\3.txt
C:\3.txt
C:\3.txt

Знаю что в коде дыра, но не могу исправить.

Последний раз редактировалось Shouldercannon; 20.03.2016 в 13:15.
Shouldercannon вне форума Ответить с цитированием
Старый 20.03.2016, 13:09   #2
newerow1989
Я самый любопытный
Участник клуба
 
Аватар для newerow1989
 
Регистрация: 24.07.2012
Сообщений: 1,949
По умолчанию

Код:
procedure TForm1.Button1Click(Sender: TObject);
var SL1,SL2,SL3:tStringList;
    i,j:integer;
    d:boolean;
begin
   SL1:=tStringList.Create;
   SL2:=tStringList.Create;
   SL3:=tStringList.Create;

   SL1.Add('C:\1.txt');
   SL1.Add('C:\2.txt');
   SL1.Add('C:\3.txt');
   SL1.Add('C:\4.txt');
   SL1.Add('C:\5.txt');

   SL2.Add('C:\1.txt');
   SL2.Add('C:\2.txt');
   SL2.Add('C:\3.txt');

   SL3.Text:=SL1.Text;
   For i:=SL3.Count-1 downto 0 do
   begin
      d:=false;
      For j:=0 to SL2.Count-1 do
         If SL3[i]=SL2[j] then
         begin
            d:=true;
            Break;
         end;
      If d then
         SL3.Delete(i);
   end;

   Memo1.Text:=SL3.Text;

   SL1.Free;
   SL2.Free;
   SL3.Free;
end;
С запрограммированным приветом, Неверов Евгений!
Сайт: http://newerow1989.ru
[Паскаль] [Delphi]
newerow1989 вне форума Ответить с цитированием
Старый 20.03.2016, 13:55   #3
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,897
По умолчанию

Нормально
Shouldercannon вне форума Ответить с цитированием
Старый 20.03.2016, 19:45   #4
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,551
По умолчанию

Тело цикла можно заменить на:
Код:
      If SL2.IndexOf(SL3[i])>=0 then
         SL3.Delete(i);
Переменные j и d выкинуть.
Arigato вне форума Ответить с цитированием
Старый 20.03.2016, 22:24   #5
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Код:
var
  idx1, idx2: int32;
begin
  // bla-bla-bla
  
  for idx1:= 0 to SL1.Count - 1 do
    begin
      repeat
        idx2:= SL2.IndexOf(SL1[idx1]);
        if idx2 <> -1
          then SL2.Delete(idx2);
      until idx2 < 0;
    
      {if SL2.Count = 0 // раскомментарить, если SL1 длинный шопипец 
        then break;}
    end; // for
    
  // в итоге в SL2 останутся только те строки, которых нет в SL1.  
end;
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 20.03.2016, 23:13   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

А если очень длинные стринглисты, что будет быстрей - удаление строк или добавление их в третий стринглист, не меняя первых два? Подозреваю, что удаление будет медленней, хотя не проверял, лень ковыряться в генофонде
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 20.03.2016, 23:19   #7
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Подозреваю, что удаление будет медленней, хотя не проверял, лень ковыряться в генофонде
я тоже, когда был маленьким с курчавой головой, подозревал. А потом полез в classes.pas и подозрения кончились.
Код:
procedure TStringList.Delete(Index: Integer);
var
  Obj: TObject;
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  // If this list owns its objects then free the associated TObject with this index
  if OwnsObjects then
    Obj := FList[Index].FObject
  else
    Obj := nil;

  // Direct memory writing to managed array follows
  //  see http://dn.embarcadero.com/article/33423
  // Explicitly finalize the element we about to stomp on with move
  Finalize(FList[Index]);
  Dec(FCount);
  if Index < FCount then
  begin
    System.Move(FList[Index + 1], FList[Index],
      (FCount - Index) * SizeOf(TStringItem));
    // Make sure there is no danglng pointer in the last (now unused) element
    PPointer(@FList[FCount].FString)^ := nil;
    PPointer(@FList[FCount].FObject)^ := nil;
  end;
  if Obj <> nil then
    Obj.Free;
  Changed;
end;
это ж лучше копирования больших кусков памяти, не так ли?
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...

Последний раз редактировалось min@y™; 20.03.2016 в 23:25.
min@y™ вне форума Ответить с цитированием
Старый 21.03.2016, 00:46   #8
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,872
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
А если очень длинные стринглисты, что будет быстрей - удаление строк или добавление их в третий стринглист, не меняя первых два? Подозреваю, что удаление будет медленней, хотя не проверял, лень ковыряться в генофонде
Удалять-то будет быстрее. Но ТС вроде не говорил о том что можно портить два первичных списка. А если сначала копировать один из списков в третий, а уж потом в нем удалять дубликаты, то вряд ли будет быстрее.

P.S. Ещё один анекдот вспоминается.
" -Как поймать две птицы?
- Очень просто. Надо поймать три птицы, а потом одну из них отпустить."
northener на форуме Ответить с цитированием
Старый 21.03.2016, 00:57   #9
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,872
По умолчанию

Цитата:
Сообщение от min@y™ Посмотреть сообщение
я тоже, когда был маленьким с курчавой головой, подозревал. А потом полез в classes.pas и подозрения кончились.
Код:
procedure TStringList.Delete(Index: Integer);
var
  Obj: TObject;
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  // If this list owns its objects then free the associated TObject with this index
  if OwnsObjects then
    Obj := FList[Index].FObject
  else
    Obj := nil;

  // Direct memory writing to managed array follows
  //  see http://dn.embarcadero.com/article/33423
  // Explicitly finalize the element we about to stomp on with move
  Finalize(FList[Index]);
  Dec(FCount);
  if Index < FCount then
  begin
    System.Move(FList[Index + 1], FList[Index],
      (FCount - Index) * SizeOf(TStringItem));
    // Make sure there is no danglng pointer in the last (now unused) element
    PPointer(@FList[FCount].FString)^ := nil;
    PPointer(@FList[FCount].FObject)^ := nil;
  end;
  if Obj <> nil then
    Obj.Free;
  Changed;
end;
это ж лучше копирования больших кусков памяти, не так ли?
А реализацию TStringList.Add ты не забыл посмотреть? И где ты там нашел копирование больщих кусков памяти?
northener на форуме Ответить с цитированием
Старый 21.03.2016, 01:30   #10
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
А реализацию TStringList.Add ты не забыл посмотреть?
нет
Цитата:
И где ты там нашел копирование больщих кусков памяти?
я имел в виду удаление из копии данных (скопировать список и удалять строки из копии уже).
Посмотрим, что автор скажет по поводу модификации входных данных.

А вообще, мне всё равно. Я всего лишь предложил альтернативный вариант.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сравнить два списка DozEL Microsoft Office Excel 3 27.04.2015 13:14
Как сравнить два string? demigod82 Общие вопросы C/C++ 3 08.05.2012 23:07
Сравнить два файла demiancz Общие вопросы Delphi 22 16.02.2011 15:29
Сравнить два множества. Pascal MaxMelnikov Помощь студентам 3 16.03.2009 09:35
Сравнить два файла Aleksandr Microsoft Office Excel 6 07.10.2008 00:22