如何首先按值对 std::map 排序,然后按键排序?

2021-12-10 00:00:00 dictionary algorithm sorting key c++

我需要先按值对 std::map 进行排序,然后再按键排序.该地图包含如下数据:

I need to sort a std::map by value, then by key. The map contains data like the following:

  1  realistically
  8         really
  4         reason
  3     reasonable
  1     reasonably
  1     reassemble
  1    reassembled
  2      recognize
 92         record
 48        records
  7           recs

我需要按顺序获取值,但关键是在值按顺序排列后,键需要按字母顺序排列.我该怎么做?

I need to get the values in order, but the kicker is that the keys need to be in alphabetical order after the values are in order. How can I do this?

推荐答案

std::map 将按 keys 对其元素进行排序.排序时它不关心 values.

std::map will sort its elements by keys. It doesn't care about the values when sorting.

您可以使用 std::vector<std::pair<K,V>> 然后使用 std::sort 后跟 std::stable_sort 对其进行排序:

You can use std::vector<std::pair<K,V>> then sort it using std::sort followed by std::stable_sort:

std::vector<std::pair<K,V>> items;

//fill items

//sort by value using std::sort
std::sort(items.begin(), items.end(), value_comparer);

//sort by key using std::stable_sort
std::stable_sort(items.begin(), items.end(), key_comparer);

第一个排序应该使用std::sort,因为它是nlog(n),然后使用std::stable_sortn(log(n))^2 在最坏的情况下.

The first sort should use std::sort since it is nlog(n), and then use std::stable_sort which is n(log(n))^2 in the worst case.

请注意,虽然选择 std::sort 是出于性能原因,但需要 std::stable_sort 才能正确排序,因为您希望按值排序被保存.

Note that while std::sort is chosen for performance reason, std::stable_sort is needed for correct ordering, as you want the order-by-value to be preserved.

@gsf 在评论中指出,如果您选择首先比较 values 的比较器,则可以使用 only std::sort,并且如果它们相等,则对 keys 进行排序.

@gsf noted in the comment, you could use only std::sort if you choose a comparer which compares values first, and IF they're equal, sort the keys.

auto cmp = [](std::pair<K,V> const & a, std::pair<K,V> const & b) 
{ 
     return a.second != b.second?  a.second < b.second : a.first < b.first;
};
std::sort(items.begin(), items.end(), cmp);

那应该是有效的.

但是等等,有一个更好的方法:存储 std::pair 而不是 std::pair 然后你根本不需要任何比较器—std::pair 的标准比较器就足够了,因为它首先比较 first(即 V)然后secondK:

But wait, there is a better approach: store std::pair<V,K> instead of std::pair<K,V> and then you don't need any comparer at all — the standard comparer for std::pair would be enough, as it compares first (which is V) first then second which is K:

std::vector<std::pair<V,K>> items;
//...
std::sort(items.begin(), items.end());

那应该很好用.

相关文章