一尘不染

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

algorithm

我需要std::map按值排序,然后按键排序。该地图包含如下数据:

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

我需要按顺序获取值,但最重要的是,在按顺序排列值之后,键必须按字母顺序排列。我怎样才能做到这一点?


阅读 206

收藏
2020-07-28

共1个答案

一尘不染

std::map将按排序其元素keys。它不在乎values排序的时间。

您可以使用std::vector<std::pair<K,V>>在排序使用std::sort之后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_sort这是n(log(n))^2最坏的情况。

请注意,虽然std::sort出于性能原因选择了,std::stable_sort但是为了保留正确的排序顺序,需要使用它来进行正确的排序。


@gsf在注释中指出, 只有 std::sort在选择values首先比较的比较器时(如果它们相等), 可以使用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<V,K>而不是,std::pair<K,V>然后根本不需要任何比较器-
标准比较器std::pair就足够了,因为它先进行比较first(即V),然后second进行比较K

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

那应该很好。

2020-07-28