• 文章
  • 动态地对键和值进行排序
发布
2014年9月24日(最后更新:2014年10月30日)

动态地对键和值进行排序

评分:3.5/5(359票)
*****
嗯,你可能在编程生涯中遇到过这个问题,或许也已经知道了答案。这个问题是关于 std::map 或 std::multimap 的,它们都是一种特殊类型的容器,可以通过比较函数指针(或像 std::less 这样的内置函数)对项目进行排序。它们在你插入新项目时就会排序,这当然非常方便,因为你不想每次需要时都调用一个排序函数!实际上,你永远不需要对 map 或 multimap 显式调用任何排序函数,因为它已经排好序了!现在,我的问题来了——
比方说,我有一个像这样的 map ——
D - 1
D - 2 
B - 3
A - 4

现在我需要像这样对它们进行排序 ——
A - 4 
B - 3 
D - 2
D - 1
排序的解释是这样的——首先,第一个元素(A、B、D)将按升序排列 A --> B --> D,而不考虑第二个元素;其次,如果第一个元素相等(这里有两个D),那么它们将按其对应的第二个元素的降序排列。
使用 std::multimap 只能完成第一部分的排序,所以我利用了模板和继承。这是代码——
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <utility>
#include <set>

using namespace std;

template <class _A, class _B, class _Compare=less<_A> >
class MMap : public set < pair< _A, _B >, _Compare >
{
        public :
                MMap():set< pair< _A, _B >, _Compare >(){};
                ~MMap(){};
};

template< typename InPair >
struct MMapComp{
        bool operator() (InPair a , InPair b){
                if( a.first == b.first ) return a.second > b.second;
                else
                        return a.first < b.first;
        }
};

int main(int argc, char ** argv)
{
        MMap<char,int,MMapComp< pair<char , int > > > test;

        test.insert(make_pair('D',1));
        test.insert(make_pair('D',2));
        test.insert(make_pair('B',3));
        test.insert(make_pair('A',4));

        for( MMap<char,int >::iterator it = test.begin(); it != test.end(); it++ )
                cout << (*it).first << "\t" << (*it).second << endl;
        return 0;
}

这是输出结果——

A	4
B	3
D	2
D	1

好吧,我为我没有写文档的代码道歉 :) 但它其实并不难读,是吗?