Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.29;
Скачать: CL | DM;

Вниз

Сравнение двух 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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.021 c
3-1091786283
Alex_Bredin
2004-08-06 13:58
2004.08.29
Получить все FK в базе


1-1092643707
an-na2002
2004-08-16 12:08
2004.08.29
Возврат к проверке


1-1092606277
Vetalich
2004-08-16 01:44
2004.08.29
Замена символов


1-1092389979
Чайник
2004-08-13 13:39
2004.08.29
StringGrid


1-1092226053
STARfish
2004-08-11 16:07
2004.08.29
Скролинг текста, отображаемого в PaintBox