![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
быстрый поиск в структуре (record)
Tonich © (2007-10-11 13:19:00)Такой вопрос
есть допустим следующие структуры
TDevice = record
Number:integer;
Outbyte:Byte;
InByte:Byte;
end;
TCOMPort = record
Devices:TList; - вот этот лист, это набор структур TDevice
Name:string
end;
TServicePorts = record
ComPorts:TList; - вот этот лист, это набор структур TCOMPort
......
end;
так вот собственно вопрос, как организовать быстрый поиск в этом последнем списке определенного устройства, то есть имя порта я знаю(Name), и номер устройства тоже (Number), для изменения значения полей.
сразу скажу, код набирал прямо тут , могут быть ошибки )
спасибо
Tonich (2007-10-11 18:09:00) [1]портов нет, штуки 4 максимум думаю будет, а вот устройств да
и еще + к этому это поиск нужет очень часто, вот поэтому и спросил про быстрый метод. ну вообщем я уже порешил как сделать, вернее сделал..
Dmitry S (2007-10-11 15:48:00) [2]А что портов так много?:)
Tonich (2007-10-11 15:35:00) [3]
> Ping (11.10.07 15:15) [7]
быстро конечно как для цикла )
я уже сделал как советовал ты и как советовали раньше, я ищу по индексам без переборов всяких ..пасибо )
Ping (2007-10-11 15:23:00) [4]Для ускорения поиска, для TCOMPort можно хранить не имя, а номер COM-порта: всяко проверка на равенство строк медленнее такой же проверки для целых чисел.
Ну, и, если надо еще быстрее, то хранить ссылки не в TList, а в обычном динамическом индексированном массиве, тогда обращение будет просто по индексу. Но если устройств не очень много, то проход по циклу в поисках нужного устройства будет ненамного длительнее, чем проверки граничных условий индекса массива плюс проверка на валидность ссылки (на случай, если в массиве есть "незанятые" ссылки на порты.)
Ping (2007-10-11 15:15:00) [5]
function TServicePorts.ComPortByName(const AName: string): TComPort;
var
i: integer;
begin
for i := 0 to ComPorts.Count - 1 do
begin
Result := TComPort(ComPorts[i]);
if (Result.Name = AName) then
Exit;
end;
raise Exception.Create('COM port not found: ' + AName);
end;
function TComPort.DeviceByNumber(ANumber: integer): TDevice;
var
i: integer;
begin
for i := 0 to Devices.Count -1 do
begin
Result := TDevice(Devices[i]);
if (Result.Number = ANumber) then
Exit;
end;
raise Exception.Create(Name + '. Device not found: ' + ANumber);
end;
function TServicePorts.FindDevice(const AName: stirng; ANumber: integer): TDevice;
begin
Result := ServicePorts.PortByName(AName).DeviceByNumber(ANumber);
end;
Так достаточно быстро?
evvcom (2007-10-11 15:06:00) [6]структуры относительно сложные, быстро никак, только перебором в циклах (IndexOf - тот же цикл внутри метода). Или если надо все же искать быстро, добавь индексацию, но задача эта уже не совсем простая.
Tonich (2007-10-11 14:57:00) [7]
> clickmaker © (11.10.07 14:19) [3]
не кажется не подойдет ( ну во-первый я храню список устройств в Tlist тоже самое помоему что и StringList.Objects а там для того что бы он вернул индекс нужно передать в IndexOf объект, а хде я его возьму если у меня есть только есть одно из возможных значений поля класса(рекорда)
Tonich (2007-10-11 14:22:00) [8]
> clickmaker © (11.10.07 14:19) [3]
пасибо учтем, я пока только собираю варианты...
clickmaker (2007-10-11 14:19:00) [9]
> быстрый поиск в этом последнем списке определенного устройства,
> то есть имя порта
StringList.Objects + IndexOf не подойдет?
Tonich (2007-10-11 14:14:00) [10]ну там вообще-то в коде не рекорды. а классы,
хорошо где и как хранить что допустим у ком порта есть столько -то устройств, (массивы не хотел делать)
Ega23 (2007-10-11 14:05:00) [11]Зачем в рекорде держать указатель на экземпляр класса?
Не, я понимаю, что не запрещено. Но зачем?