![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сравнение двух 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]Нужно обойтись без циклов. Сдвигать указатель то в одном списке, то в другом.