Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.06.2017, 11:18   #1
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию Список с уникальными идентификаторами содержащихся объектов

Здравствуйте!
Пробую сделать объект с ID и список из этих объектов, чтобы у каждого объекта ID был уникальным и постоянным в течении его времени существования.
На данный момент сделал это так:
Код:
  TNomObject = class
  public
    ID: integer;
  end;
  TNomList = class(TObjectList)
  private
    Function FindEmptyID: integer;
    function GetItem(Index: Integer): TNomObject;
    procedure SetItem(Index: Integer; const Value: TNomObject);
  public
    function FindID(NomID: Integer): Integer;
    function Add(AObject: TNomObject): Integer;
    property Items[Index: Integer]: TNomObject read GetItem write SetItem; default;
  end;

....

function TNomList.GetItem(Index: Integer): TNomObject;
begin
  Result := TNomObject(inherited GetItem(Index));
end;

procedure TNomList.SetItem(Index: Integer; const Value: TNomObject);
begin
  inherited SetItem(Index, Value);
end;

function TNomList.FindID(NomID: Integer): Integer;
begin
  For Result:=0 to Count-1 do
    If Items[Result].ID = NomID then
      exit;
  Result:=-1;
end;

Function TNomList.FindEmptyID: integer;
begin
  Result:=0;
  If count>1 then While FindID(Result)>=0 do inc(Result);
  ShowMessage(IntToStr(Result));
end;

function TNomList.Add(AObject: TNomObject): Integer;
begin
  Result := inherited Add(AObject);
  Items[Result].ID:=FindEmptyID;
end;
Есть у знатоков замечания/советы на эту тему?

Последний раз редактировалось Ship_1; 30.06.2017 в 12:01.
Ship_1 вне форума Ответить с цитированием
Старый 30.06.2017, 13:04   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Можно просто хранить какой-нибудь глобальный счетчик с последним ID.
Или GUID.

Для быстрого поиска по уникальному ID есть специальные структуры данных типа хеш-таблиц и т.п. (в разных языках/библиотеках по разному называются: hash table, dictionary, map, ...)
В старых Дельфи вроде нет стандартной реализации этого.

Цитата:
Сообщение от Ship_1 Посмотреть сообщение
постоянным в течении его времени существования
Я бы сделал его private (и public свойство/функция для его чтения) и устанавливал в конструкторе.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 30.06.2017 в 13:09.
Alex11223 вне форума Ответить с цитированием
Старый 30.06.2017, 13:15   #3
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Спасибо за комментарий. Что-то я о глобальном счётчике не подумал, но об аналогичном варианте думал: при добавлении брать ID последнего элемента и увеличивать на 1. Но я решил, что это не оптимальный способ: при удалении элемента из списка его ID становится не нужной и её можно использовать вновь. Для этого и сделал FindEmptyID.

Хеш-таблицы, наверное, интересный, но непонятный мне вариант. И программку я делаю на Delphi 7.
Ship_1 вне форума Ответить с цитированием
Старый 30.06.2017, 13:24   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Ship_1 Посмотреть сообщение
элемента из списка его ID становится не нужной и её можно использовать вновь
зачем? Вам не хватает размерности Integer?
скорее всего найти пустую ячейку будет НАМНОГО сложнее и дольше, чем просто взять очередное (следующее) значение счётчика. Без всяких заморочек.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.06.2017, 14:12   #5
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Хватает теоретически. Убедили, меняю поиск пустого ID на поиск максимального ID (чтобы в случае сохранения/загрузки списка потом можно было бы продолжить добавления)
Ship_1 вне форума Ответить с цитированием
Старый 30.06.2017, 14:32   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Ship_1 Посмотреть сообщение
Хватает теоретически
отлично.


Цитата:
Сообщение от Ship_1 Посмотреть сообщение
меняю поиск пустого ID на поиск максимального ID
если порядок не будет меняться, то максимальный ID всегда последний элемент в списке:

Код:
function TNomList.Add(AObject: TNomObject): Integer;
begin
  Result := inherited Add(AObject);
  if Result>0 
     then  Items[Result].ID:=Items[Result-1].ID+1
     else Items[Result].ID := 1;
end;
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.06.2017, 14:57   #7
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Я сначала о такой реализации и подумал, но потом передумал, решив, что возможна сортировка, которая собьёт всё. Придётся, видимо, вводить глобальную переменную или поле в TNomList.
Ship_1 вне форума Ответить с цитированием
Старый 30.06.2017, 15:03   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Ship_1 Посмотреть сообщение
возможна сортировка, которая собьёт всё.
да, сортировка собьёт.

если она возможна, тогда
Цитата:
Сообщение от Ship_1 Посмотреть сообщение
вводить ... или поле в TNomList.
private поле и методы: getMaxID, setMaxID, GetNextMaxID (получить максимальное значение, нарастить его на единицу, записать и вернуть значение) и его использовать в TNomList.Add
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.06.2017, 15:21   #9
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Ship_1
Если завести глобальную ячейку с последним освобождённым ID. То поиск будет быстрее чем хеши.

Сортировка не нужна. Достаточно хранить максимальный выделенный ID и количество свободных.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 30.06.2017, 15:22   #10
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Serge_Bliznykov, я не смог толком разобраться с property и не понял его преимущества (если они есть) по сравнению с просто переменной в классе, типа:
Код:
  TNomList = class(TObjectList)
  private
    ...
  public
    MaxID: integer;
    ...
  end;
Цитата:
Сообщение от Pavia Посмотреть сообщение
Если завести глобальную ячейку с последним освобождённым ID. То поиск будет быстрее чем хеши.
Хм, интересная мысль. Но не подходит. Как ей пользоваться, если, например, ID освобождались в такой последовательности: 4, 17, 10, 23, 4, 6?
Цитата:
Сообщение от Pavia Посмотреть сообщение
Ship_1Сортировка не нужна. Достаточно хранить максимальный выделенный ID и количество свободных.
Зачем количество свободных? Не понял... Сортировка мне по работе с программой нужна, по другим полям.

Последний раз редактировалось Ship_1; 30.06.2017 в 15:28.
Ship_1 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
список полиморфных объектов denrubun Общие вопросы C/C++ 4 17.11.2013 14:38
Добавление своих объектов в Добавление своих объектов в двунаправленный кольцевой список voidmain C# (си шарп) 3 21.03.2013 13:08
динамический список объектов tim47 Помощь студентам 0 16.05.2012 16:17
проблема с идентификаторами itwaswritten Помощь студентам 0 08.05.2010 20:34
Список полиморфных объектов kaarb Помощь студентам 0 20.06.2009 11:24