Текущий архив: 2004.12.05;
Скачать: CL | DM;
ВнизПоиск в 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;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.037 c