stringtranslate.com

Ассоциативный массив

В информатике ассоциативный массив , карта , таблица символов или словарь — это абстрактный тип данных , который хранит коллекцию пар (ключ, значение) , так что каждый возможный ключ появляется в коллекции не более одного раза. С математической точки зрения ассоциативный массив — это функция с конечной областью определения . [1] Он поддерживает операции «поиск», «удаление» и «вставка».

Проблема словаря — это классическая проблема проектирования эффективных структур данных , реализующих ассоциативные массивы. [2] Двумя основными решениями словарной проблемы являются хеш-таблицы и деревья поиска . [3] [4] [5] [6] Иногда проблему также можно решить, используя массивы с прямой адресацией , двоичные деревья поиска или другие более специализированные структуры.

Многие языки программирования включают ассоциативные массивы в качестве примитивных типов данных , в то время как многие другие языки предоставляют программные библиотеки , поддерживающие ассоциативные массивы. Память с адресацией по содержимому — это форма прямой поддержки ассоциативных массивов на аппаратном уровне.

Ассоциативные массивы имеют множество применений, включая такие фундаментальные шаблоны программирования , как мемоизация и шаблон декоратора . [7]

Название происходит не от ассоциативного свойства, известного в математике. Скорее, оно возникает из-за ассоциации значений с ключами. Его не следует путать с ассоциативными процессорами .

Операции

В ассоциативном массиве связь между ключом и значением часто называется «отображением»; то же самое слово может также использоваться для обозначения процесса создания новой ассоциации.

Операции, которые обычно определяются для ассоциативного массива: [3] [4] [8]

Ассоциативные массивы также могут включать в себя другие операции, такие как определение количества отображений или создание итератора для перебора всех отображений. Для таких операций порядок, в котором возвращаются сопоставления, обычно определяется реализацией.

Мультиотображение обобщает ассоциативный массив , позволяя связать несколько значений с одним ключом. [9] Двунаправленная карта — это связанный абстрактный тип данных, в котором сопоставления действуют в обоих направлениях: каждое значение должно быть связано с уникальным ключом, а вторая операция поиска принимает значение в качестве аргумента и ищет связанный с ним ключ. ценить.

Характеристики

Операции ассоциативного массива должны удовлетворять различным свойствам: [8]

где kи jявляются ключами, vявляется значением, Dпредставляет собой ассоциативный массив и new()создает новый пустой ассоциативный массив.

Пример

Предположим, что набор выданных библиотекой кредитов представлен в структуре данных. Каждую книгу в библиотеке может получить одновременно только один посетитель библиотеки. Однако один посетитель может иметь возможность просмотреть несколько книг. Таким образом, информация о том, какие книги и для каких посетителей проверены, может быть представлена ​​ассоциативным массивом, в котором книги являются ключами, а посетители — значениями. Используя нотацию Python или JSON , структура данных будет такой:

{ «Гордость и предубеждение» : «Алиса» , «Грозовой перевал» : «Алиса» , «Большие надежды» : «Джон» }      

Операция поиска по ключу «Большие надежды» вернет «Джон». Если Джон вернет свою книгу, это вызовет операцию удаления, а если Пэт выберет книгу, это вызовет операцию вставки, что приведет к другому состоянию:

{ «Гордость и предубеждение» : «Алиса» , «Братья Карамазовы» : «Пэт» , «Грозовой перевал» : «Алиса» }      

Выполнение

Для словарей с очень небольшим количеством сопоставлений может иметь смысл реализовать словарь с использованием списка ассоциацийсвязанного списка сопоставлений. При такой реализации время выполнения основных словарных операций линейно зависит от общего количества отображений; однако его легко реализовать, и постоянные факторы, влияющие на время его работы, невелики. [3] [10]

Другой очень простой метод реализации, который можно использовать, когда ключи ограничены узким диапазоном, — это прямая адресация в массив: значение для данного ключа k сохраняется в ячейке массива A [ k ], или если для k нет сопоставления. затем в ячейке сохраняется специальное контрольное значение , указывающее на отсутствие сопоставления. Этот метод прост и быстр: каждая операция со словарем занимает постоянное время. Однако требование к пространству для этой структуры равно размеру всего пространства ключей, что делает его непрактичным, если только пространство ключей не маленькое. [5]

Двумя основными подходами к реализации словарей являются хеш-таблица и дерево поиска . [3] [4] [5] [6]

Реализации хеш-таблиц

На этом графике сравнивается среднее количество промахов в кэше ЦП , необходимое для поиска элементов в больших хеш-таблицах (значительно превышающих размер кэша) с помощью цепочки и линейного зондирования . Линейное зондирование работает лучше благодаря лучшей локальности ссылок , однако по мере заполнения таблицы его производительность резко снижается.

Наиболее часто используемая реализация ассоциативного массива общего назначения — это хеш-таблица : массив , объединенный с хеш-функцией , которая отделяет каждый ключ в отдельный «корзину» массива. Основная идея хеш-таблицы заключается в том, что доступ к элементу массива через его индекс представляет собой простую операцию, выполняемую с постоянным временем. Таким образом, средние затраты на операцию для хеш-таблицы — это только вычисление хеша ключа в сочетании с доступом к соответствующему сегменту внутри массива. Таким образом, хеш-таблицы обычно работают за время O(1) и обычно превосходят альтернативные реализации.

Хэш-таблицы должны иметь возможность обрабатывать коллизии : сопоставление хэш-функцией двух разных ключей с одним и тем же сегментом массива. Двумя наиболее распространенными подходами к этой проблеме являются раздельная цепочка и открытая адресация . [3] [4] [5] [11] При раздельной цепочке массив не хранит само значение, а хранит указатель на другой контейнер, обычно список ассоциаций , в котором хранятся все значения, соответствующие хешу. Напротив, при открытой адресации, если обнаруживается коллизия хешей, таблица ищет пустое место в массиве для хранения значения детерминированным способом, обычно путем просмотра следующей непосредственной позиции в массиве.

Открытая адресация имеет более низкий коэффициент промахов в кэше , чем раздельная цепочка, когда таблица в основном пуста. Однако по мере того, как таблица заполняется большим количеством элементов, производительность открытой адресации снижается экспоненциально. Кроме того, в большинстве случаев раздельное связывание использует меньше памяти, если только записи не очень малы (менее чем в четыре раза больше размера указателя).

Реализации дерева

Самобалансирующиеся двоичные деревья поиска

Другой распространенный подход — реализация ассоциативного массива с самобалансирующимся двоичным деревом поиска , например деревом AVL или красно-черным деревом . [12]

По сравнению с хеш-таблицами эти структуры имеют как сильные, так и слабые стороны. В худшем случае производительность самобалансирующихся двоичных деревьев поиска значительно выше, чем у хеш-таблицы, с временной сложностью в большой записи O, равной O(log n ). В этом отличие от хеш-таблиц, в которых наихудшая производительность связана с тем, что все элементы используют один и тот же сегмент, что приводит к временной сложности O( n ). Кроме того, как и все двоичные деревья поиска, самобалансирующиеся двоичные деревья поиска сохраняют свои элементы в порядке. Таким образом, обход ее элементов следует шаблону от наименьшего к наибольшему, тогда как обход хеш-таблицы может привести к тому, что элементы будут находиться в случайном порядке. Поскольку древовидные карты упорядочены, они также могут удовлетворять запросам диапазона (находить все значения между двумя границами), тогда как хеш-карта может находить только точные значения. Однако хеш-таблицы имеют гораздо лучшую временную сложность в среднем случае, чем самобалансирующиеся двоичные деревья поиска O(1), и их производительность в наихудшем случае маловероятна при использовании хорошей хеш-функции .

Стоит отметить, что самобалансирующееся двоичное дерево поиска можно использовать для реализации сегментов для хеш-таблицы, в которой используется отдельное связывание. Это позволяет выполнять поиск констант в среднем случае, но гарантирует производительность O(log n ) в худшем случае . Однако это усложняет реализацию и может привести к еще большему ухудшению производительности для небольших хеш-таблиц, где время, затрачиваемое на вставку и балансировку дерева, превышает время, необходимое для выполнения линейного поиска по всем элементам связанного списка. или аналогичная структура данных. [13] [14]

Другие деревья

Ассоциативные массивы также могут храниться в несбалансированных двоичных деревьях поиска или в структурах данных, специализированных для определенного типа ключей, таких как счисления , массивы попыток , массивы Джуди или деревья Ван Эмде Боаса , хотя относительная производительность этих реализаций варьируется. Например, считается, что деревья Джуди работают менее эффективно, чем хеш-таблицы, в то время как тщательно выбранные хеш-таблицы обычно работают более эффективно, чем адаптивные поразрядные деревья, с потенциально более серьезными ограничениями на типы данных, которые они могут обрабатывать. [15] Преимущества этих альтернативных структур заключаются в их способности обрабатывать дополнительные операции с ассоциативными массивами, такие как поиск отображения, ключ которого наиболее близок к запрашиваемому ключу, когда запрос отсутствует в наборе отображений.

Сравнение

Заказанный словарь

Базовое определение словаря не требует порядка. Чтобы гарантировать фиксированный порядок перечисления, часто используются упорядоченные версии ассоциативного массива. У упорядоченного словаря есть два значения:

Последнее встречается чаще. Такие упорядоченные словари могут быть реализованы с использованием списка ассоциаций , путем наложения двусвязного списка поверх обычного словаря или путем перемещения фактических данных из разреженного (неупорядоченного) массива в плотный массив с упорядочением вставки.

Языковая поддержка

Ассоциативные массивы могут быть реализованы на любом языке программирования в виде пакета, и многие языковые системы предоставляют их как часть стандартной библиотеки. В некоторых языках они не только встроены в стандартную систему, но и имеют специальный синтаксис, часто с использованием индексов, подобных массивам.

Встроенная синтаксическая поддержка ассоциативных массивов была представлена ​​в 1969 году компанией SNOBOL4 под названием «таблица». TMG предлагал таблицы со строковыми ключами и целочисленными значениями. MUMPS сделал многомерные ассоциативные массивы, возможно, постоянными, своей ключевой структурой данных. SETL поддерживал их как одну из возможных реализаций наборов и карт. Большинство современных языков сценариев, начиная с AWK и включая Rexx , Perl , PHP , Tcl , JavaScript , Maple , Python , Ruby , Wolfram Language , Go и Lua , поддерживают ассоциативные массивы в качестве основного типа контейнера. Во многих других языках они доступны как библиотечные функции без специального синтаксиса.

В Smalltalk , Objective-C , .NET , [20] Python , REALbasic , Swift , VBA и Delphi [21] они называются словарями ; в Perl , Ruby и Seed7 они называются хэшами ; в C++ , C# , Java , Go , Clojure , Scala , OCaml , Haskell они называются картами (см. map (C++) , unordered_map (C++) и Map); в Common Lisp и Windows PowerShell они называются хеш-таблицами (поскольку оба обычно используют эту реализацию); в Maple и Lua они называются таблицами . В PHP все массивы могут быть ассоциативными, за исключением того, что ключи ограничены целыми числами и строками. В JavaScript (см. также JSON ) все объекты ведут себя как ассоциативные массивы со строковыми ключами, тогда как типы Map и WeakMap принимают в качестве ключей произвольные объекты. В Lua они используются как примитивный строительный блок для всех структур данных. В Visual FoxPro они называются Коллекциями . Язык D также поддерживает ассоциативные массивы. [22]

Постоянное хранение

Многим программам, использующим ассоциативные массивы, потребуется хранить эти данные в более постоянной форме, например в компьютерном файле . Распространенным решением этой проблемы является обобщенная концепция, известная как архивирование или сериализация , которая создает текстовое или двоичное представление исходных объектов, которые можно записать непосредственно в файл. Чаще всего это реализуется в базовой объектной модели, такой как .Net или Cocoa, которая включает стандартные функции, преобразующие внутренние данные в текст. Программа может создать полное текстовое представление любой группы объектов, вызывая эти методы, которые почти всегда уже реализованы в базовом классе ассоциативного массива. [23]

Для программ, использующих очень большие наборы данных, такой тип хранения отдельных файлов не подходит и требуется система управления базой данных (БД). Некоторые системы БД изначально хранят ассоциативные массивы путем сериализации данных, а затем сохранения этих сериализованных данных и ключа. Затем отдельные массивы можно загрузить или сохранить из базы данных, используя ключ для ссылки на них. Эти хранилища «ключ-значение» используются уже много лет и имеют такую ​​же историю, как и история более распространенных реляционных баз данных (RDB), но отсутствие стандартизации, среди других причин, ограничивало их использование определенными нишевыми ролями. В большинстве случаев для этих ролей использовались RDB, хотя сохранение объектов в RDB может быть сложной задачей — проблема, известная как несоответствие объектно-реляционного импеданса .

После ц.  В 2010 году потребность в высокопроизводительных базах данных, подходящих для облачных вычислений и более точно соответствующих внутренней структуре использующих их программ, привела к возрождению рынка хранилищ «ключ-значение». Эти системы могут хранить и извлекать ассоциативные массивы собственным способом, что может значительно повысить производительность в обычных рабочих процессах, связанных с Интернетом.

Смотрите также

Рекомендации

  1. ^ Коллинз, Грэм; Сайм, Дональд (1995). «Теория конечных отображений». Доказательство теорем логики высшего порядка и его приложения . Конспекты лекций по информатике. 971 : 122–137. дои : 10.1007/3-540-60275-5_61. ISBN 978-3-540-60275-0.
  2. ^ Андерссон, Арне (1989). «Оптимальные границы словарной задачи». Учеб. Симпозиум по оптимальным алгоритмам . Конспекты лекций по информатике. Спрингер Верлаг. 401 : 106–114. дои : 10.1007/3-540-51859-2_10. ISBN 978-3-540-51859-4.
  3. ^ abcde Goodrich, Майкл Т .; Тамассиа, Роберто (2006), «9.1 Абстрактный тип данных карты», Структуры данных и алгоритмы в Java (4-е изд.), Wiley, стр. 368–371
  4. ^ abcd Мельхорн, Курт ; Сандерс, Питер (2008), «4 хэш-таблицы и ассоциативные массивы», Алгоритмы и структуры данных: базовый набор инструментов (PDF) , Springer, стр. 81–98, заархивировано (PDF) из оригинала 2 августа 2014 г.
  5. ^ abcd Кормен, Томас Х .; Лейзерсон, Чарльз Э .; Ривест, Рональд Л .; Штейн, Клиффорд (2001), «11 хэш-таблиц», Введение в алгоритмы (2-е изд.), MIT Press и McGraw-Hill , стр. 221–252, ISBN 0-262-03293-7.
  6. ^ ab Дитцфельбингер М., Карлин А., Мельхорн К., Мейер ауф дер Хайде Ф., Ронерт Х. и Тарьян Р.Э. 1994. «Динамическое идеальное хеширование: верхние и нижние границы». Архивировано в 2016–2003 гг. -04 в Wayback Machine . СИАМ Дж. Компьютер. 23, 4 (август 1994 г.), 738–761. http://portal.acm.org/citation.cfm?id=182370 doi :10.1137/S0097539791194094
  7. ^ Гудрич и Тамассия (2006), стр. 597–599.
  8. ^ Аб Блэк, Пол Э.; Стюарт, Роб (2 ноября 2020 г.). "словарь". Словарь алгоритмов и структур данных . Проверено 26 января 2022 г.
  9. ^ Гудрич и Тамассия (2006), стр. 389–397.
  10. ^ «Когда мне следует использовать хеш-таблицу вместо списка ассоциаций?». lisp-часто задаваемые вопросы/часть2. 20 февраля 1996 г.
  11. ^ Кламмер, Ф.; Маццолини, Л. (2006), «Следопыты для ассоциативных карт», Ext. Рефераты ГИС-л 2006 , ГИС-I, стр. 71–74..
  12. ^ Джоэл Адамс и Ларри Найхофф. «Деревья в STL». Цитата: «Библиотека стандартных шаблонов... некоторые из ее контейнеров — шаблоны set<T>, map<T1, T2>, multiset<T> и multimap<T1, T2> — обычно создаются с использованием специального своего рода самобалансирующееся двоичное дерево поиска, называемое красно-черным деревом ».
  13. ^ Кнут, Дональд (1998). Искусство компьютерного программирования . Том. 3: Сортировка и поиск (2-е изд.). Аддисон-Уэсли. стр. 513–558. ISBN 0-201-89685-0.
  14. ^ Пробст, Марк (30 апреля 2010 г.). «Линейный и бинарный поиск» . Проверено 20 ноября 2016 г.
  15. ^ Альварес, Виктор; Рихтер, Стефан; Чен, Сяо; Диттрих, Йенс (апрель 2015 г.). «Сравнение адаптивных поразрядных деревьев и хеш-таблиц». 2015 31-я Международная конференция IEEE по инженерии данных . Сеул, Южная Корея: IEEE. стр. 1227–1238. дои : 10.1109/ICDE.2015.7113370. ISBN 978-1-4799-7964-6. S2CID  17170456.
  16. ^ "std::map". ru.cppreference.com .
  17. ^ «Класс OrderedDictionary (System.Collections.Specialized)» . Документы MS .
  18. ^ "LinkedHashMap".
  19. ^ «Коллекции — Типы данных контейнеров — Документация Python 3.9.0a3» . docs.python.org .
  20. ^ "Класс Dictionary<TKey, TValue>" . MSDN.
  21. ^ "System.Generics.Collections.TDictionary - Документация по API RAD Studio" . docwiki.embarcadero.com . Проверено 18 апреля 2017 г.
  22. ^ «Ассоциативные массивы, язык программирования D». Цифровой Марс.
  23. ^ «Руководство по программированию архивов и сериализации», Apple Inc., 2012 г.

Внешние ссылки