我有一张地图(例如,字符到整数)。我将值逐个插入此映射中。例如,这里有四个插入:
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)
我可以这样做的一种方法是使用多图。 multimap的关键是整数,值将是字符。每次插入到multimap中都需要首先检查该字符是否已存在于multimap中,并在执行插入之前删除该映射。 multimap保持按键排序,以便进行排序。
有更快的方法吗?我应该使用不同的,更有效的容器吗?
修改
这是我正在使用的C++ STL multimap。它很方便,因为它保留了元素internally ordered。
这是一个related question。我试图避免在接受的解决方案中做出建议:创建另一个地图。
答案 0 :(得分:2)
通常,地图是混洗数据结构(至少对于关联值)。 因此,对地图的元素进行排序是没有意义的。
因此,你应该使用list或array之类的东西来保持元素的排序。
我认为针对您的问题的最佳解决方案是最简单的方法:将元素存储在列表中并对其进行排序。或者你可以使用堆。
<强>更新强>
地图是一种关联容器,用于存储形成的元素 通过键值和映射值的组合。
在地图中,键值通常用于唯一标识 元素,而映射的值是某种与之关联的值 这把钥匙。键和映射值的类型可能不同。例如,a 地图的典型示例是电话指南,其名称是 密钥和电话号码是映射值。
内部,地图中的元素从低到高排序 遵循特定严格弱排序标准的键值 构造
作为关联容器,它们特别设计为 通过键有效地访问其元素(与序列不同) 容器,通过它们访问元素更有效 相对或绝对的位置)[1]。
答案 1 :(得分:2)
我会做的就是这样。想象一下,您的地图将x
映射到y
。我会创建一个struct(类,无论如何):
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
,否则插入新元素。
答案 2 :(得分:1)
根据定义,地图按其键排序。
这些值不能用于地图的排序谓词,因为这些值是非常量的!更改它们会使容器不变量无效(排序)。
如果您希望按“值”排序的条目,则显然是一键,您可能需要
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
对于许多访问来说更快
答案 3 :(得分:0)
只需使用map <char,int>
,您的密钥将保持唯一,一对<char,int>
将存储在其中。
根据元素的关联值对元素进行排序,也可以在集合中存储pair<int,char>
。