如何按值对 STL 映射进行排序?
如何实现STL映射按值排序?
例如,我有一个地图 m
:
map<int, int> m;
m[1] = 10;
m[2] = 5;
m[4] = 6;
m[6] = 1;
我想按 m
的值对该地图进行排序。因此,如果我打印地图,我希望得到如下结果:
m[6] = 1
m[2] = 5
m[4] = 6
m[1] = 10
如何以这种方式对地图进行排序?有什么方法可以处理带有排序值的键和值吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
将所有键值对转储到
set 中>
首先,其中set
是用一个小于函子构造的,该函子仅比较该对的第二个值。这样,即使您的值并不完全不同,您的代码仍然可以工作。或者将键值对转储到向量中。 >,然后使用相同的小于函子对该向量进行排序。
Dump out all the key-value pairs into a
set<pair<K, V> >
first, where theset
is constructed with a less-than functor that compares the pair's second value only. That way, your code still works even if your values aren't all distinct.Or dump the key-value pairs into a
vector<pair<K, V> >
, then sort that vector with the same less-than functor afterwards.您可以构建第二个映射,将第一个映射的值作为键,将第一个映射的键作为值。
仅当所有值都不同时,此方法才有效。如果您不能假设这一点,那么您需要构建多重地图而不是地图。
You can build a second map, with the first map's values as keys and the first map's keys as values.
This works only if all values are distinct. If you cannot assume this, then you need to build a multimap instead of a map.
根据定义,你不能。映射是一种按键对其元素进行排序的数据结构。
You can’t, by definition. A map is a data structure that sorts its element by key.
您应该使用 Boost.Bimap对于这种事情。
You should use Boost.Bimap for this sort of thing.
基于@swegi的想法,我使用 c++11 实现了一个解决方案a
multimap
:Ideone 上的代码
我还实现了一个基于 C++11 的解决方案@Chris 的想法是使用成对的向量。为了正确排序,我提供了 lambda 表达式 作为比较函子:
Ideone 上的代码
第一个解决方案更加紧凑,但两种解决方案应该具有大致相同的性能。插入到
multimap
的时间复杂度为 O(log n),但必须对 n 个条目执行此操作,导致 O( n log n)。对第二个解决方案中的向量进行排序也会导致 O(n log n)。我还尝试了@Chris关于使用一组对的想法。但是,如果值不完全不同,则该方法将不起作用。使用仅比较该对的第二个元素的函子没有帮助。如果您首先将
make_pair(1, 1)
插入集合中,然后尝试插入make_pair(2, 1)
,则不会插入第二对,因为该组将这两对视为相同。您可以在 Ideone 上看到该效果。Based on @swegi's idea, I implemented a solution in c++11 using a
multimap
:Code on Ideone
I also implemented a C++11 solution based on @Chris' idea using a vector of pairs. For correct sorting, I provide a lambda expression as comparison functor:
Code on Ideone
The first solution is more compact, but both solutions should have roughly the same performance. Inserting into a
multimap
is of O(log n), but this has to be done for n entries, resulting in O(n log n). Sorting the vector in the second solution also results in O(n log n).I also gave a try to @Chris' idea on using a set of pairs. However, it won't work if the values aren't all distinct. Using a functor that compares only the pair's second element doesn't help. If you first insert
make_pair(1, 1)
into the set and then try to insertmake_pair(2, 1)
, then the second pair won't be inserted, because both pairs are seen as identical by that set. You can see that effect here on Ideone.我刚刚在我的 C++ 书中做了一个类似的问题。我想出的答案可能不是很有效:
I've just done a similar question in my c++ book. The answer I came up with might not be very efficient though:
创建另一个映射,根据值而不是键提供 less() 函数,并且如果 value1 <= value2 (不严格是 < ),则该函数应返回 true。在这种情况下,也可以对具有非不同值的元素进行排序。
Create another map, provide a less() function based on the value not key, AND the function should return true if the value1 <= value2 (not strictly < ). In this case, elements with non-distinct values can be sorted as well.
我在 thispointer 中找到了这个。该示例对 std::map< 进行排序std::string,int>由所有 int 值组成。
I have found this in thispointer. The example sorts a std::map< std::string,int> by all the int values.
在某些情况下可以做的一件事是使用>>的比较器函数
vector>
而不是使用maps
。这样你就失去了使用map的好处,例如更少的查找时间,但你可以直接使用带有向量One thing that could be done in some scenarios, is using a
vector<pair<int, int>>
rather than usingmaps<int, int>
. In this way you lose the benefits of using map, such as the less lookup time but you can directly use comparator function with vector<pair<int, int>>地图已经根据第一个键进行排序,如果您想根据第二个值对其进行排序,请将第二个值作为键。其他人使用另一个容器,如向量>。
map is already sorded based on the first key, if you want to sort it based on the second value make second value as key. otherwies use another container like vector<pair<int,int>>.
最近不得不做这个。我最终使用了指针...
快速基准测试结果
Recently had to do this. I ended up using pointers...
Quick Benchmark Results
此代码使用自定义排序函数按值对地图进行排序
This code uses custom sorting function to sort map by values