C++ 以vualue排序一个map
为了找工作重新拾起 C++.才发现,被 Python 宠坏后,再回头使用 c++,一下子无法适应如此复杂的情况.
回到正题,C++ 中如何排序一个 map.
我们都知道无法使用 std::sort
来排序 map,只有通过间接的方法.参考 stackoverflow 上的几个答案.
- sorting map using value
- std::map how to sort by value, then by key
- C++ how to copy a map to a vector
我们假设输入为一组数字,输出为数字和其出现次数,以出现次数从大到小排序,若出现次数相同,则数字小的先输出.
样例输入为 1 2 3 3 4 5 5 2
以下代码均来自(或改自) stackoverflow.
第一种方法为将map中的key和value对换,装入multimap中,multimap输出时有序.
#include <map> #include <algorithm> #include <iostream> template<typename A, typename B> std::pair<B, A> flip_pair(const std::pair<A, B> &p) { return std::pair<B, A>(p.second, p.first); } template<typename A, typename B> std::multimap<B, A> flip_map(const std::map<A, B> &src) { std::multimap<B, A> dst; std::transform(src.begin(), src.end(), std::inserter(dst, dst.begin()), flip_pair<A, B>); return dst; } int main (void) { std::map<int, int> num_count; std::map<int, int>::iterator map_it; int num; while(std::cin >> num) num_count[num]++; for (const auto & n : num_count) std::cout << n.first << : << n.second << std::endl; std::cout << std::endl; std::multimap<int, int> dst_map = flip_map(num_count); for (const auto & n : dst_map) std::cout << n.second << : << n.first << std::endl; return 0; }
此时输出为
1 : 1 4 : 1 5 : 2 2 : 2 3 : 2
虽然是按出现次数排序,但并未满足第二条件.
要想使用自定义的比较方法排序,一种方法为将map输入到一个vector中,在自定义cmp方法,使用algorith库中sort方法来排序
#include <map> #include <algorithm> #include <iostream> #include <vector> int main (void) { std::map<int, int> num_count; std::map<int, int>::iterator map_it; int num; while(std::cin >> num) num_count[num]++; std::vector<std::pair<int, int> > dst_vec; std::copy(num_count.begin(), num_count.end(), std::back_inserter(dst_vec)); auto cmp = [](std::pair<int, int> const & a,std::pair<int, int> const & b) { return a.second != b.second ? a.second > b.second : a.first < b.first; }; std::sort(dst_vec.begin(),dst_vec.end(), cmp); for(const auto & n : dst_vec) std::cout << n.first << : << n.second << std::endl; return 0; }
此时输出为
2 : 2 3 : 2 5 : 2 1 : 1 4 : 1
满足条件