【问题标题】:What is the difference between set vs map in C++?C ++中的set与map有什么区别?
【发布时间】:2014-02-28 07:12:13
【问题描述】:

我仍然对 STL 中 map 和 set 数据结构之间的差异感到困惑。我知道 set 是以排序的方式存储值,那么 map 呢?它是否按排序顺序存储值? Map存储值对(key,value),这个特性有什么好处?

【问题讨论】:

  • 从语义上讲,set 和 map 是完全不同的数据结构。您应该通过一个很好的教程来学习何时使用哪个。
  • 它们都是关联容器,不是吗?默认情况下,它们使用std::less 作为比较器,并且遵循严格的顺序。
  • 您可以将集合想象成一个哈希,其中仅使用键而未使用值。
  • 在 STL 的上下文中,最好不要设置为哈希。 unordered_set 是用 hash 实现的,set 是 not.

标签: c++ stl


【解决方案1】:

至少对于有序版本(std::mapstd::set),map 通过允许您引入外部密钥 (map::key_type) 来确定否则无法从 map 的数据类型 (map::mapped_type) 派生的元素。如果排序可以完全从map::mapped_type 派生(通过比较两个元素),那么您通常最好使用set,在这种情况下,您将避免将键复制为map::key_type

在某种程度上,std::map 是多余的,您始终可以使用std::set 来代替,方法是引入一种新的元素类型,该类型将键与数据聚合在一起,同时提供必要的比较功能。然而,这很麻烦并且通常不优雅。

澄清为什么set 可能比map 更麻烦; set<key, data> 对存储为一个元素,而 map 将保持 2 之间的分隔。这意味着,例如,对于 set 上的 find 操作,其中 find 的参数是现场构造的,整个 <key, data> 元素将必须构造,而它实际上位于 key 上,这是 find 操作所需的。然后,set 元素的data 成员的构造是多余的,并且如果data 成员代表磁盘存储或涉及一些其他复杂或耗时的构造操作,则效率可能相当低。 map 只需构造 find 所需的实际 key 即可缓解这种情况。

总而言之,考虑一个元素<key, data>,您想知道是使用map 还是set 来存储多个有序元素。如果key 跨越整个data(意味着data 是空的,否则key == data)那么您最好使用set,在这种情况下您将避免a)复制key 存储和b ) 可能必须保持 2 keys 同步。如果key 不包含在data 中,那么(你必须)使用map。棘手的部分是keydata 的(正确)子集。然后,您必须权衡维护重复的 keys(对于 map)与构建不与 key 重叠的 data(对于 set)的成本,后者find 操作可能会发生这种情况。

【讨论】:

  • 一个重点是,集合中的元素一旦放入集合中就不能更改[cplusplus.com/reference/set/set/]如果您以有序的方式存储简单数据项的集合,那么一套可以工作。如果要存储由一个数据成员排序的结构,并且希望能够更改结构中的其他数据,请将排序数据成员取出作为键并使用映射。
  • 如果您使其他数据成员可变,则可以。
【解决方案2】:

从概念上讲,set 是事物的集合,而映射是键到值的映射。

【讨论】:

    【解决方案3】:

    map 存储已排序的键。它将键映射到值。通常它被实现为键的二叉搜索树 (red-black tree)。 set 是一个值不相关的映射。 unordered_mapunordered_set(C++11 中的新功能)存储未排序的键并使用哈希表进行搜索。

    【讨论】:

      【解决方案4】:

      std::mapstd::set 非常相似。它们都有一个有序的唯一键集合。此外,map 具有与每个键关联的值。

      【讨论】:

        【解决方案5】:

        std::map 是一个关联容器,用于存储具有唯一键的键值对。 std::set 也是一个关联容器,用于存储一组排序器对象(或键)。

        你应该看看std::mapstd::set

        【讨论】:

        • 地图以哪种方式存储值?基于密钥?如果是基于key的store,key是排序的吗?
        • 集合并不是真正的关联——集合的内容不会与其他任何东西“关联”。
        • 地图中的元素始终按照其内部比较对象指示的特定严格弱排序标准按其键排序
        • 各位,我明白了。在 Map 中,数据也是按键排序的。我从链接“键是通过使用比较功能排序”得到的。
        • @seand sets 在 C++ 标准中被视为“关联容器”。它可能是违反直觉的,并且可能源于实现类似于映射的事实,除了只存储键。但这是我们现在坚持使用的术语。
        猜你喜欢
        • 1970-01-01
        • 2011-03-15
        • 2010-10-26
        • 2014-03-15
        • 2011-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多