插入式地图

Insertion sort of a map

本文关键字:地图 插入      更新时间:2023-10-16

我有一个映射(例如,从字符到整数(。我把值一个接一个地插入到这个映射中。例如,这里有四个插入:

1: A -> 1
2: B -> 2
3: C -> 3
4: D -> 1

我想根据映射键的关联值对它们进行排序。因此,在每次插入时,我都会得到排序后的输出:

1: A(1)
2: B(2), A(1)
3: C(3), B(2), A(1)
4: C(3), B(2), A(1), D(1)

此外,我希望能够覆盖现有的映射,以保持键(字符(的唯一性。所以第五个插入:

5: A -> 27

将导致排序输出为:

5: A(27), C(3), B(2), D(1)

我可以这样做的一种方法是使用多映射。多映射的键将是整数,值将是字符。每次插入到多映射中都首先需要检查字符是否已经存在于多映射中,并在执行插入之前删除该映射。多映射保持键的顺序,从而负责排序。

有更快的方法吗?我应该使用一个不同的、更高效的容器吗?

编辑

这是我正在使用的C++STL多映射。它很方便,因为它使元素在内部保持有序。

这是一个相关的问题。我尽量避免做公认的解决方案中建议的事情:创建另一个地图。

我会做这样的事情。想象一下您的地图将x映射到y。我会创建一个结构(类,不管怎样(:

struct element
{
    map_this_t x;
    to_this_t  y;
    bool operator < (element &rhs)
    {
        return y < rhs.y;       // sorted based on y
    }
};

然后创建一个set<element>并插入其中。如果您对集合中的所有数据进行迭代,那么您可以按照所需的顺序获得数据。插入时,首先搜索是否存在x值为所需值的元素。如果是,只需更新y,否则插入一个新元素。

通常,映射是一个混洗的数据结构(至少对于相关值(。因此,对地图的元素进行排序是没有意义的。

因此,您应该使用类似列表或数组的东西来保持元素的排序。

我认为解决问题的最佳方法是最简单的方法:将元素存储在列表中并进行排序。或者可以使用堆。

更新:

映射是一种关联容器,用于存储形成的元素通过键值和映射值的组合。

在映射中,键值通常用于唯一标识元素,而映射的值是与这把钥匙。键和映射值的类型可能不同。例如地图的典型示例是电话指南,其中的名称是键,并且电话号码是映射的值。

在内部,映射中的元素按从低到高的顺序排列遵循上设置的特定严格弱排序标准的键值建设

作为关联容器,它们被特别设计为通过密钥有效地访问其元素(不同于序列容器,通过其相对或绝对位置([1]。

[1]http://www.cplusplus.com/reference/stl/map/

映射根据定义按其键排序。

不能在映射的排序谓词中使用这些值,因为这些值是非常数!更改它们将使容器不变量(排序(无效。

如果您希望条目按"value"排序,它是一个隐含的密钥,并且您可能需要

std::set<std::pair<key, value> >

更新这里有一个工作演示:https://ideone.com/SgbEN

相反。为了能够通过不同的谓词重新排序,您需要一个列表、向量或任何其他顺序容器。

编辑

列表解决方案效率太低了,因为我必须在每次插入后进行排序,而且没有有效的方法来保持键的唯一性。

这里的解决方案是使用

  • std::make_heap
  • std::push_heap
  • std::sort_heap

算法。它们与列表(以及用于廉价value_types的向量,或者使用c++0x移动语义(配合良好

如果在按顺序使用列表之前无法承担sort_heap步骤:请使用

insert_point = std::lower_bound(lst.begin(), lst.end(), insertee);
st.insert(insertion_point, insertee);

直接插入有序位置。您可以预期push_heap对于多次插入会更快,而lowerbound/insert对于多次访问会更快。

只需使用一个map <char,int>,您的密钥将保持唯一,一对<char,int>将存储在其中。

基于元素的相关值对元素进行排序也将CCD_ 13存储在一个集合中。