地图和字典有啥区别?
Posted
技术标签:
【中文标题】地图和字典有啥区别?【英文标题】:What is the difference between a map and a dictionary?地图和字典有什么区别? 【发布时间】:2011-02-22 11:12:35 【问题描述】:我知道映射是将键映射到值的数据结构。字典不一样吗?地图和字典有什么区别1?
1.我不是在问它们是如何用语言 X 或 Y 定义的(这似乎是人们在 SO 上通常所问的),我想知道它们在理论上有什么区别。
【问题讨论】:
【参考方案1】:同一事物的两个术语:
“地图”被Java、C++使用 “字典”被.Net、Python使用 “关联数组”被php使用“地图” 是正确的数学术语,但由于它在 functional programming 中具有单独的含义而被避免使用。
有些语言还使用其他术语(javascript 中的“Object”,Ruby 中的“Hash”,Lua 中的“Table”),但这些在编程中也有不同的含义,所以我会避开他们。
请参阅here 了解更多信息。
【讨论】:
JAVA不是同时有Map和Dictionary吗?有什么区别? @vivek_jonam: Java 中的Dictionary
已过时。它是一个抽象类,在创建Map
接口之前使用。
我知道这个问题与语言无关,所以这是正确的答案,但我最终在这里寻找 Java 两者兼有的原因,所以这个评论对我来说真的很完美。
"table"在lua中使用。
Javascript 现在也有一个“地图”数据结构 (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)【参考方案2】:
一个是另一个的旧术语。通常在数学术语“地图”出现之前使用术语“字典”。此外,字典往往有一个键类型的字符串,但并非所有地方都 100% 正确。
【讨论】:
【参考方案3】:计算机科学术语摘要:
字典是表示一组元素的数据结构,具有插入、删除和成员资格测试;元素可能(但不一定)由不同的 key 和 value 部分组成
map 是一个 关联 数据结构,能够存储一组 键,每个键与一个相关联(或有时不止一个 - 例如 C++ 多图)value,仅在给定键的情况下,能够访问和擦除现有条目。 p>
讨论
回答这个问题很复杂,因为程序员已经看到在他们使用的特定语言或系统中赋予了更具体含义的术语,但这个问题要求“在理论上”进行与语言无关的比较,我的意思是 在计算科学术语中。
术语解释
牛津大学计算机科学词典列出:
例如,我们有一组元素 A, B, C, D... ,我们可以插入并开始删除,我们可以查询 "is C在场吗?”。字典表示一组元素的任何数据结构,可以支持元素的插入和删除以及成员资格测试
map 的计算科学概念是基于数学语言术语 mapping,牛津词典将其定义为:
因此,map 数据结构提供了一种从 给定集合中的元素(在映射到第二组中的一个或多个元素 - 称为关联的“value(s)”。 "...or more elements in the second set" 方面可以通过两种不同的方式实现: 许多映射实现强制键的唯一性,并且只允许每个键与一个值相关联,但该值本身可能是包含许多更简单数据类型的值的数据结构,例如 1,"one", "ichi", 2, "two", "ni" 说明由字符串对/集合组成的值。 其他映射实现允许重复键,每个映射到相同或不同的值 - 这在功能上满足“关联...每个 [key] 元素...与...多个 [多于一个] [value] 元素”的情况.例如, 1, "one", 1, "ichi", 2, "two", 2, "ni" 。映射一种将给定集合(域)的每个元素与第二个集合(范围)的一个或多个元素相关联的操作。
字典和地图对比
因此,使用上面严格的 Comp Sci 术语,如果接口恰好支持并非每个字典都需要的附加操作,则字典只是一个映射:
能够存储具有不同 key 和 value 组件的元素
能够检索和擦除仅给定键的值
一个微不足道的转折:
map 接口可能不直接支持对 key,value 对是否在容器中的测试,这在元素恰好是 key,value 对的字典中是迂腐的要求;地图甚至可能没有测试键的功能,但最坏的情况是您可以查看尝试的键值检索是成功还是失败,然后如果您关心您可以检查您是否检索到预期值。李>明确地与您的听众交流
⚠ 尽管如此,如果您在上面解释的严格的计算科学含义中使用 dictionary,请不要期望您的听众最初会关注您,或者在您分享和捍卫术语时留下深刻印象.这个问题的其他答案(以及他们的赞成票)表明,在大多数程序员的经验中,“dictionary”与“map” 同义的可能性有多大。尝试选择更广泛、更明确的术语:例如
关联容器:任何存储键/值对的容器,具有值检索和键擦除功能 哈希映射:关联容器的哈希表实现 强制唯一键的哈希集:存储元素/值的字典的哈希表实现,而不将它们视为包含不同的键/值组件,其中元素的重复项不能插入 平衡二叉树映射支持重复键:...使用特定实现交叉引用 Comp Sci 术语
C++ 标准库
映射:map
、multimap
、unordered_map
、unordered_multimap
其他词典:set
、multiset
、unordered_set
、unordered_multiset
注意:使用迭代器或std::find
,您可以擦除元素并测试array
、vector
、list
、deque
等中的成员资格,但容器接口不直接支持,因为发现一个元素在 O(N) 时效率非常低,在某些情况下插入/擦除效率低下,并且支持这些操作会破坏容器所暗示的故意限制的 API - 例如deque
s 应该只支持前后擦除/弹出,而不是某些键。不得不在代码中做更多的工作来编排搜索,这会温和地鼓励程序员切换到具有更高效搜索的容器数据结构。
...以后可能会添加其他语言/随时编辑...
【讨论】:
牛津 CS 的定义完全是错误的,因为根据该定义,“字典”只是“集合”的同义词,而显然不是。 “字典”的显着特征是每个条目都有一个键(服从于集合语义)和一个关联的值。这对应于传统的自然语言词典,其中每个术语都有一个定义 @DavidBooth:我将首先解决你的最后一句话,指出在讨论“传统自然语言词典”时的用法没有特别要求与计算科学中的用法相匹配。这使您句子的其余部分成为“牛津 CS 定义完全错误”,因为您没有以这种方式使用或理解该术语。很难令人信服。为了合理地与这样的参考争论,你需要调查重要的 Comp Sci。教科书或讲座,看看这个词在学术环境中是如何被实际使用的——我希望牛津大学能做到这一点。 我的意思不是自然语言定义与 CS 定义相同。当然不是:CS 定义更精确,尽管选择 CS 术语是为了唤起自然语言定义。我的观点是,牛津 CS 的定义显然是错误的,因为根据他们的定义,“字典”将与“集合”相同,但事实并非如此。如果您不同意这一点,那么您真的必须阅读一些有关数据结构的 CS 书籍。 (我还有一些计算机科学学士、硕士和博士学位,并且仍然记得很清楚。)希望澄清一下。 @DavidBooth 好吧,您的 cmets 在这里供读者考虑。我寻找更多的确认 - 我在网上找到的第一本教科书来自斯坦福 - Ullman 的Foundations of Computer Science,其中说“字典抽象数据类型是一种集合,在其上执行特定的操作——插入、删除和查找”。示例清楚地表明字典不需要具有键/值对。直到/除非您从备受推崇的文本中引用实际定义,否则我不会改变我的答案。 从技术上讲,字典确实是“一种集合”,因为它是一个映射,一个映射就是一组对。但是仅仅将字典描述为一个集合是非常误导的,因为这忽略了它是一个映射的意义。如果字典只是一个集合,那么称它为字典就没有意义了。 Ullman本人恰好在this slide上澄清了“字典”的含义。【参考方案4】:我的 2 美分。
Dictionary 在 Java 中是一个抽象类,而 Map 是一个接口。由于 Java 不支持多重继承,如果一个类扩展了 Dictionary,它就不能扩展任何其他类。
因此,引入了 Map 接口。
字典类已过时,首选使用地图。
【讨论】:
虽然这个答案是正确的,但问题发布者指出:I am not asking for how they are defined in language X or Y
。这个答案是 Java 特定的。【参考方案5】:
通常我假设一个映射是由一个哈希表支持的;它意味着一个无序的商店。 字典意味着有序的商店。
有一个基于树的字典,称为Trie。
在 Lisp 中,它可能如下所示:
(a (n (d t)) n d )
里面封装了几个字:
一个 和 蚂蚁 一个 广告从顶部到叶子的遍历产生一个单词。
【讨论】:
.Net 中的Dictionary
是无序的。
Cocoa 字典也是无序的。
C++ std::map
是有序的,标准中没有规定它的实现,std::unordered_map
是在 c++11 中引入的,它是通过哈希实现的
@HaraldScheirich - 虽然 C++ 标准没有明确规定“您应该使用红黑树来实现 std::map
”,但请尝试使用其他任何东西。 AVL 树不起作用;它的插入成本不符合标准。哈希不起作用;哈希是无序的,因此不符合标准。该标准几乎没有明确说明“你应该使用红黑树来实现std::map
”。
+1。尽管字典在许多平台上是无序的,但这个词意味着一个顺序。我更喜欢术语地图。【参考方案6】:
其实不是一回事。地图是字典的子集。字典被定义为here 具有插入、删除和查找功能。 Java 使用的 Map(根据this)是一个字典,要求键映射到值被严格映射为一对一的函数。字典可能有多个键映射到一个值,或者一个键映射到多个值(如在哈希表中链接),例如 Twitter 主题标签搜索。
作为一个更“真实世界”的例子,在字典中查找一个单词可以为我们提供同一个单词的多个定义,当我们找到一个条目将我们指向另一个条目(参见另一个词)时,相同定义列表的单词数。在现实世界中,地图要广泛得多,允许我们有名称的位置或坐标的名称,但我们也可以找到最近的邻居或其他属性(人口等),所以恕我直言,可能有更大的扩展map 类型可能具有基于图形的实现,但最好始终只假设键值对,特别是因为最近的邻居和值的其他属性都可能只是值的数据成员。
尽管有一对一的要求,但如果值被概括为集合本身,或者如果值只是对存储在其他地方的集合的引用,则 java 映射可以实现更像通用字典的东西。
请记住,Java 维护者不是 ADT 定义的维护者,Java 决策专门针对 Java。
【讨论】:
【参考方案7】:这个概念的其他相当常见的术语:关联数组和哈希。
【讨论】:
哈希与此无关。这是一种快速检测物体是否不同的方法。您正在考虑一个 hashmap,它使用一个 hash 来完成 Map/Dictionary 工作。 @DJClayworth 不,许多编程语言实际上将这些东西称为哈希。见Ruby。不是我设计的,我也不会这么称呼它,但不要射信使。【参考方案8】:是的,它们是相同的,您可以添加“关联数组”。
使用Hashtable
或Hash
通常指的是实现。
【讨论】:
【参考方案9】:这是同一个概念的两个不同术语。Hashtable
和 HashMap
也指同一个概念。
【讨论】:
实际上,Hashtable/Hashmap 在它们的名字中暗示了一个特定的实现(相对于平衡树,例如在 C++ std::map 中使用)。 一般来说,你不应该关心实现。 (性能原因除外)此外,这并不总是正确的;以 .Net 为例。【参考方案10】:在纯理论层面上。
字典是可用于定位链接值的值。 地图是一个值,它提供有关如何定位其他值的说明
所有允许非线性访问(即只获取第一个或最后一个)的集合都是一个映射,因为即使是一个简单的数组也有一个映射到正确值的索引。因此,虽然 Dictionary 是一种地图类型,但地图的可能功能范围要广得多。
实际上,它通常是定义名称的映射函数,因此 HashMap 是一种映射数据结构,它使用哈希算法将键链接到值,而字典没有指定键的链接方式到一个值,因此可以通过链表、树或任何其他算法存储。从使用端来看,您通常并不关心算法只知道它们的工作原理,因此您使用通用字典,并且仅在您需要执行算法类型时才转移到其他结构之一
【讨论】:
【参考方案11】:主要区别在于 Map 要求所有条目(值和键对)都具有唯一键。如果发生冲突,即当新条目与集合中已有的条目具有相同的键时,则需要进行冲突处理。
通常,我们使用分离链来处理冲突。或线性探测。
字典允许将多个条目链接到同一个键。
当地图实现了分离链时,它往往类似于字典。
【讨论】:
【参考方案12】:我现在在数据结构类中,我的理解是 dict() 数据类型也可以初始化为字典 = 或键和值,与列表/数组的方式基本相同数据类型用于实现堆栈和队列。因此,dict() 是类型,maps 是结果数据结构,您可以选择使用字典数据类型实现,就像您可以使用列表类型并选择使用它实现堆栈或队列数据结构一样。
【讨论】:
以上是关于地图和字典有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章