Яка різниця між картою та словником?


199

Я знаю, що карта - це структура даних, яка відображає ключі до значень. Чи словник не той самий? Яка різниця між картою та словником 1 ?


1. Я не запитую, як вони визначаються мовою X або Y (що, здається, те, про що люди зазвичай запитують тут, про SO), я хочу знати, в чому полягає їхня різниця в теорії.


Чудове запитання!
NoName

Відповіді:


262

Два терміни для одного і того ж:

  • "Карта" використовується Java, C ++
  • "Словник" використовується .Net, Python
  • "Асоціативний масив" використовується PHP

"Карта" - це правильний математичний термін, але його уникають, оскільки він має окреме значення у функціональному програмуванні .

Деякі мови використовують ще інші терміни ("Об'єкт" в Javascript, "Хеш" в Ruby, "Таблиця" в Lua) , але всі вони також мають окремі значення в програмуванні, тому я б їх уникав.

Дивіться тут для отримання додаткової інформації.


7
Хіба в JAVA не є і карта, і словник? Які відмінності там?
vivek_jonam

36
@vivek_jonam: Dictionaryу Java застаріла. Це абстрактний клас, використовуваний до створення Mapінтерфейсу.
BlueRaja - Danny Pflughoeft

7
Я знаю, що питання є агностичним мовою, тому це правильна відповідь, але я опинився тут, шукаючи причину, у якої ява була в обох, тому цей коментар був для мене справді ідеальною справою.
GrandOpener

1
"стіл" використовується в луа.
Дедуплікатор

1
це також дещо заплутано називається "Об'єкт" в JSON (з історичних причин, пов’язаних із JavaScript)
Квільйон

20

Один - це більш старий термін, а інший. Зазвичай термін "словник" вживався до того, як математичний термін "карта" вжився. Крім того, словники, як правило, мають ключовий тип рядка, але це не на 100% вірно скрізь.


10

Мої 2 копійки.

Словник є абстрактним класом на Java, тоді як Map є інтерфейсом. Оскільки Java не підтримує декілька успадкувань, якщо клас розширює словник, він не може поширювати жоден інший клас.

Тому було введено інтерфейс Map.

Клас словників є застарілим, і використання карт Map є кращим.


9

Відповідь на це запитання ускладнюється тим, що програмісти побачили терміни, що дають більш конкретні значення у певних мовах чи системах, які вони використовували, але це запитання вимагає порівняння мовного агностику "теоретично", що я маю на увазі під термінами Computing Science .

Термінологія пояснила

Словник інформатики Оксфордського університету перелічує:

словник будь-якої структури даних, що представляє собою набір елементів, який може підтримувати вставлення та видалення елементів, а також перевірку на членство

  • Наприклад, у нас є набір елементів {A, B, C, D ...}, які ми змогли вставити і могли почати видаляти, і ми можемо запитувати "чи присутній C?" .

Поняття обчислювальної науки про карту засноване на математичному лінгвістичному терміні відображення , який Оксфордський словник визначає як:

відображення Операція, яка асоціює кожен елемент заданого набору (домену) з одним або декількома елементами другого набору (діапазон).

  • Таким чином, структура даних карт забезпечує спосіб переходу від елементів заданого набору - відомі " клавіші " на карті, до одного або декількох елементів у другому наборі - відомих як пов'язані " значення (и)" ".
  • В «... або більш елементів , у другому наборі» аспект може бути підтриманий реалізації є два різні способи:
    • Багато реалізацій карти забезпечують унікальність ключів і дозволяють асоціювати кожен ключ з одним значенням, але це значення може бути самою структурою даних, що містить безліч значень більш простого типу даних, наприклад {{1, {"one" , "ichi"}, {2, {"два", "ni"}}} ілюструє значення, що складаються з пар рядків.
    • Інші реалізації карт дозволяють повторювати ключі для кожного відображення на однакові або різні значення - що функціонально задовольняє випадку "асоціювати ... кожен [ключ] елемент ... з ... більше [ніж один] [значення] елементів". Наприклад, {{1, "one"}, {1, "ichi"}, {2, "two"}, {2, "ni"}}.

Словник та карта протиставлені

Отже, використовуючи вище сувору термінологію Comp Sci, словник - це лише карта, якщо інтерфейс підтримує додаткові операції, не потрібні кожному словнику:

  • можливість зберігати елементи з різними компонентами ключа та значення

  • можливість отримати значення (и), задані лише ключем

Тривіальний поворот:

  • інтерфейс карти може не підтримувати безпосередньо перевірку того, чи є пара {ключ, значення} в контейнері, що педантично є вимогою до словника, де елементами є {ключ, значення} пар; карта може навіть не мати функції тестування ключа, але в гіршому випадку ви можете побачити, чи спроба пошуку значення за ключем успішна чи не вдалася, тоді, якщо вам все одно, ви можете перевірити, чи ключ отримав очікуване значення.

Спілкуйтеся однозначно зі своєю аудиторією

⚠ Незважаючи на все вищесказане, якщо ви використовуєте словник у суворому значенні Computing Science, поясненому вище, не сподівайтесь, що ваша аудиторія спостерігає за вами спочатку або не будете вражені, коли ви ділитесь та захищаєте термінологію. Інші відповіді на це питання (та їхні результати) показують, наскільки ймовірно, що "словник" буде синонімом "карти" у досвіді більшості програмістів. Спробуйте вибрати термінологію, яка буде більш зрозумілою та однозначно зрозумілою: напр

  • асоціативний контейнер : будь-який контейнер, що зберігає пари ключів / значень із значенням вилучення та стирання за ключем
  • хеш-карта : реалізація хеш-таблиці асоційованого контейнера
  • хеш-набір, що виконує виконання унікальних ключів : реалізація хеш-таблиці словника, що зберігає елемент / значення, не розглядаючи їх як такі, що містять окремі компоненти ключ / значення, при цьому дублікати елементів не можна вставити
  • балансова двійкова карта дерева, що підтримує повторюваний ключ : ...

Перехресне посилання термінології Comp Sci з конкретними реалізаціями

Стандартна бібліотека C ++

  • карти: map, multimap, unordered_map,unordered_multimap
  • інші словники: set, multiset, unordered_set,unordered_multiset
  • Примітка: з ітераторами або std::findви можете видалити елемент і тест на членство в array, vector, list, і dequeт.д., але контейнері інтерфейси безпосередньо не підтримують , що з - за перебування елемента ефектно неефективно в O (N), в деяких випадках вставки / стирання неефективність, і підтримка цих операцій підриває навмисно обмежений API, який контейнер має на увазі - наприклад, deques повинен підтримувати стирання / виправлення спереду та ззаду, а не з точки зору якогось ключа. Необхідність зробити більше роботи над кодом, щоб упорядкувати пошук, обережно спонукає програміста перейти до структури даних контейнера з більш ефективним пошуком.

... може додати інші мови пізніше / не соромтесь редагувати в ...


3

Зазвичай я припускаю, що карта підтримується хеш-таблицею; він конотує не упорядкований магазин. Словники означають замовлений магазин.

Існує словник на основі дерева, який називається Trie .

У Ліспі це може виглядати приблизно так:

(a (n (d t)) n d )

Який інкапсулює слова:

  • а
  • і
  • мураха
  • ан
  • оголошення

Прохід зверху до листа дає слово.


4
Dictionaryв. Net є не упорядкованим.
BlueRaja - Danny Pflughoeft

2
Словники какао також не упорядковані.
Кен

C ++ std::mapзамовлено: його реалізація не визначена в стандарті, std::unordered_mapвведено в c ++ 11, реалізовано через хеш
Харальд Шейріх

3
@HaraldScheirich - Хоча стандарт C ++ спеціально не говорить "ти будеш використовувати червоно-чорне дерево для втілення std::map", спробуйте використовувати що-небудь інше. Дерево AVL не працюватиме; це витрати на вставку не відповідають стандартним. Хеш не буде працювати; хеш не упорядкований, а значить, не відповідає стандарту. Стандарт майже говорить: "Ви будете використовувати червоно-чорне дерево для реалізації std::map", не говорячи прямо.
Девід Хаммен

+1. Хоча словники не упорядковані на багатьох платформах, слово означає порядок. Мені більше подобається термін map.
nawfal

2

Не насправді те саме. Карти - це підмножина словника. Словник визначається тут як наявність вставки, видалення і пошуку функцій. Карта, якою користується Java (відповідно до цього ), є словником з вимогою, щоб ключі, які відображають значення, суворо відображалися як функція "один на один". У словнику може бути більше однієї ключової карти на одне значення або одна ключова карта з кількома значеннями (наприклад, ланцюжком в таблицю переходів), наприклад, пошук хештегів у Twitter.

Як більш "реальний" приклад, пошук слова в словнику може дати нам ряд визначень для того ж слова, і коли ми знайдемо запис, який вказує нам на інший запис (див. Інше слово), кількість слів для того ж списку визначень. У реальному світі карти набагато ширші, що дозволяє нам розміщувати місця для імен чи імен для координат, але також ми можемо знайти найближчого сусіда чи інші атрибути (популяції тощо), тому ІМХО може бути аргументом для більшого розширення тип карти, щоб, можливо, були виконані на основі графіків, але найкраще завжди вважати лише парами ключ-значення, тим більше, що найближчий сусід та інші атрибути до значення можуть бути лише членами даних значення.

Java-карти, незважаючи на вимогу "один на один", можуть реалізувати щось більше, як узагальнений словник, якщо значення узагальнено як саму колекцію або якщо значення є лише посиланнями на колекції, що зберігаються в іншому місці.

Пам’ятайте, що Java-сервіси - це не підтримувачі визначення ADT, а рішення Java - спеціально для Java.


1

Інші терміни цього поняття, які досить поширені: асоціативний масив та хеш.


1
Хеш з цим ні до чого. Це метод швидкого виявлення, чи відрізняються об'єкти. Ви думаєте про хешмап, який використовує хеш, щоб виконувати завдання Map / Dictionary.
DJClayworth

5
@DJClayworth Ні, багато мов програмування насправді називають ці речі хешами. Дивіться Рубі . Я цього не розробляв і не називав би це, але не стріляйте в месенджер.
Хенк Гей

1

Так, вони однакові, ви можете додати в асортимент "Асоціативний масив".

використання Hashtable або Hashater відноситься до реалізації.


1

так на чисто теоретичному рівні.

Словник - це значення, яке можна використовувати для пошуку пов'язаного значення. Карта - це значення, яке дає вказівки, як знайти інші значення

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

На практиці це звичайно функція відображення, яка визначає ім'я, тому HashMap - це структурована карта даних, яка використовує алгоритм хешування для прив’язки ключа до значення, де як словник не визначає, як ключі пов'язані зі значенням тому може зберігатися через пов'язаний список, дерево або будь-який інший алгоритм. з кінця використання вам, як правило, байдуже, який алгоритм працює лише тому, що ви використовуєте загальний словник і переходите до однієї з інших структур лише тоді, коли вам потрібно передати тип алгоритму


-1

Це два різні терміни для одного поняття.
Hashtableа HashMapтакож посилаються на ту саму концепцію.


3
Насправді, Hashtable / Hashmap мають на увазі конкретну реалізацію у своїй назві (порівняно з урівноваженим деревом, яке використовується, наприклад, у C ++ std :: map).
Джо

Взагалі, вам не варто дбати про реалізацію. (За винятком причин продуктивності) Також це не завжди так; подивіться, наприклад, .Net.
СЛАкс

-2

Основна відмінність полягає в тому, що карта вимагає, щоб усі записи (параметри значень і ключів) мали унікальний ключ. Якщо трапляються зіткнення, тобто коли новий запис має той самий ключ, що і запис, який уже є у колекції, тоді потрібно керувати зіткненням.

Зазвичай ми обробляємо зіткнення, використовуючи або роздільне ланцюг . Або лінійне зондування .

Словник дозволяє кілька записів , які будуть пов'язані з тим же ключем.

Коли карта реалізує роздільне ланцюжок, вона, як правило, нагадує словник.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.