Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
ВнизСравнение двух TStringList-ов Найти похожие ветки
← →
Pavelkq (2004-08-10 15:27) [0]Здравствуйте!
Имею два 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% записей.
Что я делаю не так?
← →
Sandman25 © (2004-08-10 15:32) [1]Нужно обойтись без циклов. Сдвигать указатель то в одном списке, то в другом.
← →
Pavelkq (2004-08-10 15:46) [2]А можно наглядно? Я пока еще чайник:-(
← →
Sandman25 © (2004-08-10 15:52) [3]Первый список
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 16:02) [4]Так это и есть мой старый алгоритм цикла. По первому списку все равно пробегаем в цикле. Еще проблема в том, что в малом списке могут быть элементы, которых нет во втором списке. Тогда сдвиг указателя обоих списков на 1 приведет к ошибке, т.е. через один в малом списке элеменn может совпасть в текущим в большом. Списки же из string-ов.
← →
TUser © (2004-08-10 16:04) [5]// Есть отсортированные 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-13 12:53) [6]Большое спасибо! Даже не подозревал, что строковые переменные можно сравнить > или <. Отлично работает!
← →
TUser © (2004-08-13 13:15) [7]Чего? Их нельзя так сравнивать. Я же написал
ф-цию сравнения строк сам реализуй,
Т.е. надо написать свою процедуру или испаользовать готовую - AnsiCompareStr.
← →
TUser © (2004-08-13 13:16) [8]Хотя нет - действительно можно. А я и сам не знал :)
← →
Думкин © (2004-08-13 13:16) [9]> [7] TUser © (13.08.04 13:15)
Почему? Попробуй.
← →
AlexSV (2004-08-13 13:56) [10]Кстати при использовании 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;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.08.29;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.034 c