Форум программистов, компьютерный форум, киберфорум
bedvit
Войти
Регистрация
Восстановить пароль
Рейтинг: 5.00. Голосов: 2.

unordered map в СOM, быстрая хеш-таблица, содержащая пары: уникальный ключ-значение

Запись от bedvit размещена 01.07.2021 в 17:36
Обновил(-а) bedvit 01.07.2021 в 22:42

Реализация в COM ассоциативного контейнера, содержащего пары ключ-значение с уникальными ключами. Поиск, вставка и удаление элементов имеют среднюю постоянную сложность.
Часть библиотеки BedvitCOM (начиная с v1.0.4.7, в XLL c v2.0.1.5)
Использован стандартный контейнер С++: std::unordered_map (хеш-таблица)

КЛЮЧ: можно использовать любые данные (не включая ссылки на массивы и объекты), ключ хранится как строка (конвертируется, если нужно, из другого типа данных).

ЗНАЧЕНИЕ: можно использовать любые данные (включая ссылки на массивы, объекты и даже на другую хеш-таблицу)

interface IUnorderedMap : IDispatch
Кликните здесь для просмотра всего текста

[id(1), helpstring("Find")] HRESULT Find([in] VARIANT key, [in, out, optional] VARIANT* value, [out, retval] VARIANT* result);
[id(2), helpstring("Insert")] HRESULT Insert([in] VARIANT key, [in] VARIANT value, [out, retval] VARIANT* result);
[id(3), helpstring("InsertOrAssign")] HRESULT InsertOrAssign([in] VARIANT key, [in] VARIANT value, [out, retval] VARIANT* result);
[id(4), helpstring("Erase")] HRESULT Erase([in] VARIANT key, [out, retval] VARIANT* result);
[id(5), helpstring("Clear")] HRESULT Clear();
[id(6), helpstring("Size")] HRESULT Size([out, retval] LONG* result);
[id(7), helpstring("RangeSet")] HRESULT RangeSet([in] VARIANT range, [out, retval] LONG* result);
[id(8), helpstring("RangeGet")] HRESULT RangeGet([out] VARIANT* range, [in, defaultvalue(0)] LONG lowerBound, [out, retval] LONG* result);


Методы:
1.Find (key,value) - Поиск значения по ключу, возвращает true, если найден. Если value задан - возвращает значение (опционально)
2.Insert(key,value) - Вставляет пару ключ-значения по ключу, возвращает true, если успешно, false - если ключ уже есть (не перезаписывается)
3.InsertOrAssign(key,value) - Вставляет или перезаписывает пару ключ-значения по ключу, возвращает true, если создан новый и false если обновлен уже существующий.
4.Erase(key) - Удаляет пару ключ-значения по ключу, возвращает true, если успешно.
5.Clear() - Очистить весь контейнер.
6.Size() - Возвращает размер контейнера (количество пар ключ-значение)
7.RangeSet(VARIANT range) - Вставляет пары ключ-значения из массива/диапазона, возвращает количество вставленных пар ключ-значение. Из дубликатов - загружается только первый по порядку.
8.RangeGet(VARIANT range, lowerBound) - Возвращает количество выгруженных элементов в массив с указанной нижней границей массива (по умолчанию = 0)
Следуя названию контейнера, стоит упомянуть, что порядок пар ключ-значение, определяется внутренней реализацией контейнера, и может не совпадать ни с порядком добавления пар, ни с каким-либо еще порядком сортировки и т.д.
т.е. порядок элементов загруженного массива, может не совпадать с порядком элементов выгруженного.
+хранятся только уникальные ключи, т.е. все последующие дубликаты не будут добавлены из исходного массива.


Проведенные тесты и сравнения с Collection и Dictionary (быстрее от нескольких раз до нескольких порядков)


Пример использования в VBA
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Sub UnorderedMap()
Dim key, value, value2, sizeU, x, arrU
Dim U As New BedvitCOM.UnorderedMap 'раннее связывание
'Dim U: Set U = CreateObject("BedvitCOM.UnorderedMap") 'позднее связывание
 
key = "key" 'ключ
value = "value" 'значение
If Not U.Insert(key, value) Then MsgBox "Элемент уже существует и не был обновлен"
If Not U.InsertOrAssign(key, value) Then MsgBox " = False (False - Элемент обновлен, True - то создан новый)"
If Not U.Find(key, value2) Then MsgBox "Не удалось найти элемент" 'выводим найденный результат по ключу
If Not U.Erase(key) Then MsgBox "Не удалось удалить элемент" 'очистка элемента по ключу
 
x = U.RangeSet(Range("a1:b5").value) 'x - количество загруженных элементов в map (первый дубликат)
x = U.RangeGet(arrU, 1) 'x - количество выгруженных элементов в массив '1-нижняя граница массива
Range("c1").Resize(x, 2) = arrU
 
Debug.Print U.Size 'количество элементов контейнера
U.Clear 'очистить весь контейнер
End Sub
Размещено в Без категории
Показов 541 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.