Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];

Вниз

Поиск в TStringList по первым символам его строк.   Найти похожие ветки 

 
Кириешки ©   (2004-11-19 11:28) [0]

Есть TStringList содержащий 97 тыс. строк загружаемых из файла.
Мне надо чтобы можно было производить поиск в нем по ПЕРВЫМ символам его строк. Ну, чтобы было примерно так :
Допустим есть TStringList заполненый n-ным кол-вом строк, листбокс и едит. В едите пишется например "аб" и в листбокс поподают все строки из TStringList начинающиеся на "аб". Подскажите пожалуйста как это реализовать, и если можно с примерчиком.


 
ЮЮ ©   (2004-11-19 11:36) [1]

TStringList должен быть отсортирован.
в едит.ончэйндж очищаешь листбокс, методом половинного деления очень быстро найдешь первую строку, совпадающую по маске и начиная с неё добавляешь в листбокс, пока строки удовлетворяют маске


 
Кириешки ©   (2004-11-19 11:41) [2]

ЮЮ

А как искать - то я не понял?


 
sniknik ©   (2004-11-19 11:43) [3]

len:= Length(Edit.Text);
for i:= 0 to StringList.Count-1 do
 if copy(StringList.Strings[i], 1, len)="аб" then
  листбокс.Add(StringList.Strings[i]);

но вообщето с 97 тыс строк уже можно думать о базах данных ;о)). или хотябы использовать базовые компоненты с их фильтрами, индексами, сортировкой, ...


 
begin...end ©   (2004-11-19 11:49) [4]


> [2] Кириешки ©   (19.11.04 11:41)


> А как искать - то я не понял?

Та же написано - методом половинного деления.


 
ЮЮ ©   (2004-11-19 11:52) [5]

ну, например, так:

function FindFirst(List:TstringList; const Mask: String): integer;
var
 cr, l, len, r, t: integer;
begin
 if Mask = "" then begin
   Result := -1;
   Exit;
 end;
 len := length(Mask);
 l := 0;
 r := List.Count - 1;
 t := (l + r) div 2;
 while l <= r do begin
   cr := AnsiCompareText(Copy(List[t], 1, len), Mask);
   if cr = 0 then begin
     result := t;
     exit;
   end else if cr < 0 then
     l := t + 1
   else
     r := t - 1;
   t := (l + r) div 2;
 end;
 result := -1;
end;


 
***SPIDER***   (2004-11-19 11:55) [6]

Примерно так:
...
StringList1.LoadFromFile(...);
...
procedure TForm1.Edit1Change(...);
var i,n:integer;
begin
 ListBox1.Clear;
 if StringList1.Count>0 then
 for i:=0 to StringList1.Count-1 do
 begin
   if Copy(StringList1.Strings[i],1,Length(Edit1.Text))=Edit1.Text then
   ListBox1.Items.Add(StringList1.Strings[i]);
 end;
end;
...

Конечно методом половинного деления будет эффективнее, но лень писать.


 
Кириешки ©   (2004-11-19 12:07) [7]

Спасибо всем!

А что такое метод половинного деления? :((


 
ЮЮ ©   (2004-11-19 12:13) [8]

каждый раз область поиска сокращаешь в 2 раза, анализируя значение посередине.


 
begin...end ©   (2004-11-19 12:22) [9]


> [7] Кириешки ©   (19.11.04 12:07)

> А что такое метод половинного деления?


Попробую объяснить. Только прошу всех не делать выводов о моей озабоченности. Я просто посмотрел на адрес e-mail товарища Кириешки.

Вот представь. Находишься ты в коридоре, в котором есть ряд из 11 дверей. За дверьми, в комнатах, сидят женщины - по одной в каждой комнате. Известно, что чем больше номер двери, тем больше возраст женщины, находящейся в соответствующей комнате. Тебе, например, нравятся только 20-летние.

Заходишь ты в среднюю (6-ю) дверь. А там сидит 10-летняя девочка. Понятно, что за дверьми с номерами меньше 6 находятся вообще младенцы (см. условие выше). А то, что нужно тебе, находится между 7-й и 11-й дверьми (включительно). Поэтому про двери  номерами, меньшими 7, забываешь. Делишь оставшийся отрезок (от 7 до 11) пополам, получаешь 9. Заходишь, там сидит бабушка 70-ти лет. Тебе это не подходит, причём очевидно, что за двери с номерами больше 9 лучше не заглядывать. Оставшиеся двери, которые нужно просмотреть: 7..8. За одной из этих дверей твоя красавица и сидит.


 
Мастер ©   (2004-11-19 12:26) [10]

 TFilteredList=class(TStringList)
 private
   FFilteredList:TStrings;
   FFilter: String;
   isFiltered: Boolean;
   procedure SetFiltered(const Value: Boolean);
   function GetCountFiltered: Integer;
   procedure ChangeFilter;
   procedure SetFilter(const Value: String);
   function GetFilteredItem(const index: Integer): String;
 public
   constructor Create;
   destructor Destroy; override;

   property Filter: String read FFilter write SetFilter;
   property CountFiltered: Integer read GetCountFiltered;
   property Filtered: Boolean read isFiltered write SetFiltered;
   property FilteredItems[const index: Integer]: String read GetFilteredItem;
   property FilteredList: TStrings read FFilteredList;
 end;

procedure TFilteredList.ChangeFilter;
var
 i: Integer;
 Len: Integer;
begin
 FFilteredList.Clear;
 if Filter="" then isFiltered := False;
 if not Filtered then Exit;
 Len := Length(FFilter);
 for i := 0 to Count-1 do
 begin
   if Copy(Self[i],1,Len)=FFilter then FFilteredList.Add(Self[i]);
 end;
end;

constructor TFilteredList.Create;
begin
 inherited Create;
 FFilteredList := TStringList.Create;
end;

destructor TFilteredList.Destroy;
begin
 FFilteredList.Free;
 inherited;
end;

function TFilteredList.GetCountFiltered: Integer;
begin
 Result := FFilteredList.Count;
end;

function TFilteredList.GetFilteredItem(const index: Integer): String;
begin
 Result := FFilteredList[index];
end;

procedure TFilteredList.SetFilter(const Value: String);
begin
 if FFilter=Value then Exit;
 FFilter := Value;
 ChangeFilter;
end;

procedure TFilteredList.SetFiltered(const Value: Boolean);
begin
 isFiltered := Value;
 ChangeFilter;
end;



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.121 c
3-1099930125
dbd
2004-11-08 19:08
2004.12.05
синхронизация обновлений в многопользовательских системах


3-1099778094
Mih@s
2004-11-07 00:54
2004.12.05
IBDataSet и Params


1-1100870196
Romul
2004-11-19 16:16
2004.12.05
Получение версии из ресурсного файла.


1-1101302963
Саша
2004-11-24 16:29
2004.12.05
Макроподстановка


14-1100534465
vasilii
2004-11-15 19:01
2004.12.05
profiler для Delphi7





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский