Jump to content

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

(Перенаправлено из Словаря (структура данных) )

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

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

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

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

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

Операции

[ редактировать ]

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

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

Вставьте или поставьте
добавить новый соедините его с коллекцией, сопоставив ключ с его новым значением. Любое существующее сопоставление перезаписывается. Аргументами этой операции являются ключ и значение.
Удалить или удалить
удалить пара из коллекции, отделяя заданный ключ от его значения. Аргумент этой операции является ключевым.
Ищи, найди или получи
найдите значение (если есть), привязанное к данному ключу. Аргументом этой операции является ключ, а значение возвращается из операции. Если значение не найдено, некоторые функции поиска вызывают исключение , а другие возвращают значение по умолчанию (например, ноль, ноль или определенное значение, переданное конструктору).

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

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

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

[ редактировать ]

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

  • lookup(k, insert(j, v, D)) = if k == j then v else lookup(k, D)
  • lookup(k, new()) = fail, где fail это исключение или значение по умолчанию
  • remove(k, insert(j, v, D)) = if k == j then remove(k, D) else insert(j, v, remove(k, D))
  • remove(k, new()) = new()

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

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

{
    "Pride and Prejudice": "Alice",
    "Wuthering Heights": "Alice",
    "Great Expectations": "John"
}

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

{
    "Pride and Prejudice": "Alice",
    "The Brothers Karamazov": "Pat",
    "Wuthering Heights": "Alice"
}

Выполнение

[ редактировать ]

Для словарей с очень небольшим количеством сопоставлений может иметь смысл реализовать словарь с использованием списка ассоциаций , который представляет собой связанный список сопоставлений. При такой реализации время выполнения основных операций со словарем линейно зависит от общего количества сопоставлений. Однако его легко реализовать, и постоянные факторы, влияющие на время его работы, невелики. [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] Преимущества этих альтернативных структур заключаются в их способности выполнять дополнительные операции с ассоциативными массивами, такие как поиск сопоставления, ключ которого наиболее близок к запрашиваемому ключу, когда запрос отсутствует в наборе сопоставлений.

Сравнение

[ редактировать ]
Базовая структура данных Поиск или удаление Вставка Заказал
средний худший случай средний худший случай
Хэш-таблица О(1) На ) О(1) На ) Нет
Самобалансирующееся двоичное дерево поиска О( вход ) О( вход ) О( вход ) О( вход ) Да
несбалансированное двоичное дерево поиска О( вход ) На ) О( вход ) На ) Да
Последовательный контейнер пар ключ-значение
(например, список ассоциаций )
На ) На ) О(1) О(1) Нет

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

[ редактировать ]

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

  • Порядок перечисления всегда является детерминированным для данного набора ключей путем сортировки. Это относится к реализациям на основе дерева, одним из представителей которых является <map> контейнер C++. [16]
  • Порядок перечисления не зависит от ключа и вместо этого основан на порядке вставки. Это относится к «упорядоченному словарю» в .NET Framework , LinkedHashMap в Java и Python . [17] [18] [19]

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

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

[ редактировать ]

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

Встроенная синтаксическая поддержка ассоциативных массивов была представлена ​​в 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. Перейти обратно: Перейти обратно: а б с д и Гудрич, Майкл Т .; Тамассиа, Роберто (2006), «9.1 Тип абстрактных данных карты», Структуры данных и алгоритмы в Java (4-е изд.), Wiley, стр. 368–371
  4. Перейти обратно: Перейти обратно: а б с д Мельхорн, Курт ; Сандерс, Питер (2008), «4 хэш-таблицы и ассоциативные массивы», Алгоритмы и структуры данных: базовый набор инструментов (PDF) , Springer, стр. 81–98, заархивировано (PDF) из оригинала 2 августа 2014 г.
  5. Перейти обратно: Перейти обратно: а б с д Кормен, Томас Х .; Лейзерсон, Чарльз Э .; Ривест, Рональд Л .; Штейн, Клиффорд (2001), «11 хэш-таблиц», Введение в алгоритмы (2-е изд.), MIT Press и McGraw-Hill , стр. 221–252, ISBN  0-262-03293-7 .
  6. Перейти обратно: Перейти обратно: а б Дитцфельбингер М., Карлин А., Мельхорн К., Мейер ауф дер Хайде Ф., Ронерт Х. и Тарьян Р.Э. 1994. «Динамическое идеальное хеширование: верхняя и нижняя границы». Архивировано 4 марта 2016 г. на Wayback Machine . СИАМ Дж. Компьютер. 23, 4 (август 1994 г.), 738–761. http://portal.acm.org/citation.cfm?id=182370 дои : 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. ^ «ЛинкедХэшМап» .
  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 г.
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: f95573a85ea7025719d114f0b42b173e__1721050920
URL1:https://arc.ask3.ru/arc/aa/f9/3e/f95573a85ea7025719d114f0b42b173e.html
Заголовок, (Title) документа по адресу, URL1:
Associative array - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)