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

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

Сравнение двух TStringList-ов [D6, WinXP]


Pavelkq ©   (2004-08-10 15:27:00) 

Здравствуйте!
Имею два TStringList-а. Один маленький (тысячи записей), другой - огромный (сотни тысяч записей). Задача - сравнить маленький с большим и выделить элементы, которые совпали в новый список.
Сначала я делал цикл в цикле, что было невероятно долго. Потом я отсотрировал оба списка и второй цикл уже проводился с номера последнего выхода. Таким образом время значительно сократилось. Теперь решил попробовать функцию Find, но что-то не получается.
Делаю примерно так:

Procedure  Poisk();
var FinderBl : Boolean;
   FinderInt: Integer;
   Raven:TStringList; // Список, куда попадут совпавшие элементы
Begin
Raven:=TStringList.create;
TSL.Sort;
TData.Sort;
TSL.Sorted:=True;
TData.Sorted:=True;

For i:=0 to TData.Count-1 do
  begin
     FinderBl:=TSL.Find(TData[i1],FinderInt);
     if FinderBl then Begin
        ShowMessage ('Ура!!! Есть!!!');
        Raven.Add(TData[i1]);
        end; // If      
  end; // For
end;

 TData- маленький список
 TSL - большой
К сожалению, после этой процедуры в Raven ничего не попадает и радостное сообщение ни разу не появляется. Хотя старинным методом цикла в цикле равенства выявлялись в 80% записей.
 Что я делаю не так?


AlexSV   (2004-08-13 13:56:00) [1]

Кстати при использовании AnsiCompareStr можно обойтись вообще одной проверкой:

i:=0; j:=0;
while (i < Str1.Count) and (j < Str2.Count) do
case AnsiCompareStr(Str1.Strings[i], Str2.Strings[j]) of
-1: inc (i);
1: inc (j);
else
begin
ResStr.Add(Str1.Strngs[i]);
inc (i); inc(j);
end;
end;


TUser   (2004-08-13 13:16:00) [2]

Хотя нет - действительно можно. А я и сам не знал :)


Думкин   (2004-08-13 13:16:00) [3]

> [7] TUser ©   (13.08.04 13:15)

Почему? Попробуй.


TUser   (2004-08-13 13:15:00) [4]

Чего? Их нельзя так сравнивать. Я же написал
ф-цию сравнения строк сам реализуй,
Т.е. надо написать свою процедуру или испаользовать готовую - AnsiCompareStr.


Pavelkq   (2004-08-13 12:53:00) [5]

Большое спасибо! Даже не подозревал, что строковые переменные можно сравнить > или <. Отлично работает!


TUser   (2004-08-10 16:04:00) [6]

// Есть отсортированные Str1 и Str2
i:=0; j:=0;
while (i < Str1.Count) and (j < Str2.Count) do
if Str1.Strings[i] < Str2.Strings[j] then // ф-цию сравнения строк сам реализуй
inc (i)
else
if Str1.Strings[i] > Str2.Strings[j] then
inc (j)
else begin
// if Str1.Strings[i] = Str2.Strings[j] then begin
ResStr.Add(Str1.Strngs[i]);
inc (i); inc(j);
end;


Pavelkq   (2004-08-10 16:02:00) [7]

Так это и есть мой старый алгоритм цикла. По первому списку все равно пробегаем в цикле. Еще проблема в том, что в малом списке могут быть элементы, которых нет во втором списке. Тогда сдвиг указателя обоих списков на 1 приведет к ошибке, т.е. через один в малом списке элеменn может совпасть в текущим в большом. Списки же из string-ов.


Sandman25   (2004-08-10 15:52:00) [8]

Первый список
1 2 3 6 8

Второй список
2 4 5 6 7 9

Имеем, что переменные указывают на
1
2
затем
2
2 - совпадение
затем
3
4
затем
6
4
затем
6
5
затем
6
6 - совпадение
затем
8
7
затем
8
9
затем
достигнут конец обоих списков, конец алгоритма


Pavelkq   (2004-08-10 15:46:00) [9]

А можно наглядно? Я пока еще чайник:-(


Sandman25   (2004-08-10 15:32:00) [10]

Нужно обойтись без циклов. Сдвигать указатель то в одном списке, то в другом.


Наверх

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