首页 > 代码库 > 内置容器的排序规则构造方式

内置容器的排序规则构造方式

转自:http://lhearen.top/2016/08/27/Sort-for-Built-in-Containers/

C ++中有很多内置的容器,我们可以轻松有效地实现我们想要的内容。 然而,有时它们的排序能力相对有限,因此,我们必须提出自定义比较器来重新定义排序功能。 

几乎所有的函数/容器(例如priority_queue除外)都要求排序满足严格弱排序的标准数学定义,否则函数/容器的行为将不会被定义。

  • 方法:
  1. 定义 operator<()

   如果你希望自定义类的对象能够像往常的原始类型一样自然排序,则可以使用此方法。 如果要保持原有的排序特性,返回<,否则>。(此处用>表示 重载了运算符<号)

   

技术分享
 1 class Edge{
 2 public:
 3     int from, to , weight;
 4     Edge(int a, int b, int c): from(a), to(b), weight(c){}
 5     bool operator < (Edge other) const{
 6         return weight < other.weight;
 7     }
 8 };
 9 int main()
10 {
11     vector<Edge> edges;
12     for(int i = 0; i < 10; ++i) edges.emplace_back(i, i+2, 20-i);
13     cout<<"Original vector: "<<endl;
14     for(int i = 0; i < 10; ++i) cout<<edges[i].weight<<",";
15     cout<<endl;
16     cout<<"Sorted ascending vector: "<<endl;
17     sort(edges.begin(), edges.end());
18     for(int i = 0; i < 10; ++i) cout<<edges[i].weight<<",";
19     cout<<endl;
20     random_shuffle(edges.begin(), edges.end());
21     cout<<"Shuffled vector: "<<endl;
22     for(int i = 0; i < 10; ++i) cout<<edges[i].weight<<",";
23     cout<<endl;
24     cout<<"Ascending set: "<<endl;
25     set<Edge> edgeSet(edges.begin(), edges.end());
26     for(auto e: edgeSet) cout<<e.weight<<",";
27     cout<<endl;
28     cout<<"Keys ascending map: "<<endl;
29     map<Edge, int> edgeMap;
30     for(int i = 0; i < edges.size(); ++i) edgeMap[edges[i]] = i*5;
31     for(auto& pair: edgeMap) cout<<"key: "<<pair.first.weight<<",";
32     cout<<endl;
33     cout<<"Descending max heap: "<<endl;
34     priority_queue<Edge> maxHeap(edges.begin(), edges.end());
35     while(maxHeap.size()){
36         cout<<maxHeap.top().weight<<",";
37         maxHeap.pop();
38     }
39     cout<<endl;
40     return 0;
41 }
View Code

输出如下:

技术分享
 1 Original vector: 
 2 20,19,18,17,16,15,14,13,12,11,
 3 Sorted ascending vector: 
 4 11,12,13,14,15,16,17,18,19,20,
 5 Shuffled vector: 
 6 17,11,14,16,18,19,15,12,13,20,
 7 Ascending set: 
 8 11,12,13,14,15,16,17,18,19,20,
 9 Keys ascending map: 
10 key: 11,key: 12,key: 13,key: 14,key: 15,key: 16,key: 17,key: 18,key: 19,key: 20,
11 Descending max heap: 
12 20,19,18,17,16,15,14,13,12,11,
View Code

Set and map

技术分享
 1 struct cmpClass{
 2     bool operator()(const int& a, const int& b) const {
 3         return a > b;
 4     }
 5 };
 6 int main()
 7 {
 8     int myints[] = {10, 60, 50, 20};
 9     vector<int> v(myints, myints+4);
10     auto cmpFunc = [](const int a, const int b) { return a > b; };
11     cout<<"Sorted int vector using lambda function: "<<endl;
12     sort(v.begin(), v.end(), [](const int a, const int b) { return a < b; });
13     for(int i = 0; i < v.size(); ++i) cout<<v[i]<<",";
14     cout<<endl;
15     random_shuffle(v.begin(), v.end());
16     cout<<"Shuffled int vector: "<<endl;
17     for(int i = 0; i < v.size(); ++i) cout<<v[i]<<",";
18     cout<<endl;
19     sort(v.begin(), v.end(), cmpFunc);
20     cout<<"Sorted int vector using cmpFunc: "<<endl;
21     for(int i = 0; i < v.size(); ++i) cout<<v[i]<<",";
22     cout<<endl;
23     cout<<"Ascending int set using less<int>: "<<endl;
24     set<int, less<int>> lessSet(v.begin(), v.end());
25     for(auto n: lessSet) cout<<n<<",";
26     cout<<endl;
27     cout<<"Descending int set using cmpFunc: "<<endl;
28     set<int, decltype(cmpFunc)> funcSet(cmpFunc);
29     for(int i = 0; i < v.size(); ++i) funcSet.insert(v[i]);
30     for(auto n: funcSet) cout<<n<<",";
31     cout<<endl;
32     cout<<"Descending int set using cmpClass: "<<endl;
33     set<int, cmpClass> classSet(v.begin(), v.end());
34     for(auto n: classSet) cout<<n<<",";
35     cout<<endl;
36     cout<<"Descending keys in map using greater<int>: "<<endl;
37     map<int, int, greater<int>> greaterMap;
38     for(int i = 0; i < v.size(); ++i) greaterMap[v[i]] = v[i]*3;
39     for(auto& pair: greaterMap) cout<<"key: "<<pair.first<<",";
40     cout<<endl;
41     cout<<"Descending keys in map using cmpFunc: "<<endl;
42     map<int, int, decltype(cmpFunc)> funcMap(cmpFunc);
43     for(int i = 0; i < v.size(); ++i) funcMap[v[i]] = 2*v[i];
44     for(auto& pair: funcMap) cout<<"key: "<<pair.first<<",";
45     cout<<endl;
46     cout<<"Descending keys in map using cmpClass: "<<endl;
47     map<int, int, cmpClass> classMap;
48     for(int i = 0; i < v.size(); ++i) classMap[v[i]] = 3*v[i];
49     for(auto& pair: classMap) cout<<"key: "<<pair.first<<",";
50     cout<<endl;
51     return 0;
52 }
View Code

输出如下:

技术分享
 1 Sorted int vector using lambda function: 
 2 10,20,50,60,
 3 Shuffled int vector: 
 4 10,60,50,20,
 5 Sorted int vector using cmpFunc: 
 6 60,50,20,10,
 7 Ascending int set using less<int>: 
 8 10,20,50,60,
 9 Descending int set using cmpFunc: 
10 60,50,20,10,
11 Descending int set using cmpClass: 
12 60,50,20,10,
13 Descending keys in map using greater<int>: 
14 key: 60,key: 50,key: 20,key: 10,
15 Descending keys in map using cmpFunc: 
16 key: 60,key: 50,key: 20,key: 10,
17 Descending keys in map using cmpClass: 
18 key: 60,key: 50,key: 20,key: 10,
View Code

Priority_queue

  • primitive types including int, float, …, and pair;
  • cmpClass for comparer;
  • cmpFunction for comparer.
技术分享
 1 struct cmpClass{
 2     bool operator()(const int a, const int b) const {
 3         return a < b;
 4     }
 5 };
 6 int main()
 7 {
 8     int myints[] = {10, 60, 50, 20};
 9     vector<int> v(myints, myints+4);
10     cout<<"Sorted ascending vector using less<int>: "<<endl;
11     sort(v.begin(), v.end(), less<int>());
12     for(int i = 0; i < v.size(); ++i) cout<<v[i]<<",";
13     cout<<endl;
14     cout<<"Min heap using greater<int>: "<<endl;
15     priority_queue<int, vector<int>, greater<int>> minIntHeap(myints, myints+4);
16     while(minIntHeap.size()) {
17         cout<<minIntHeap.top()<<",";
18         minIntHeap.pop();
19     }
20     cout<<endl;
21     vector<pair<int, int>> vv;
22     for(int i = 0; i < 10; ++i) vv.emplace_back(20-i, i);
23     cout<<"Unsorted pair vector: "<<endl;
24     for(int i = 0; i < vv.size(); ++i) cout<<vv[i].first<<",";
25     cout<<endl;
26     cout<<"Sorted ascending pair vector: "<<endl;
27     sort(vv.begin(), vv.end(), less<pair<int, int>>());
28     for(int i = 0; i < vv.size(); ++i) cout<<vv[i].first<<",";
29     cout<<endl;
30     cout<<"Min heap using greater<pair<int, int>>: "<<endl;
31     priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> minPairHeap(vv.begin(), vv.end());
32     while(minPairHeap.size()){
33         cout<<minPairHeap.top().second<<",";
34         minPairHeap.pop();
35     }
36     cout<<endl;
37     cout<<"Max heap using cmpClass to compare int: "<<endl;
38     priority_queue<int, vector<int>, cmpClass> maxClassHeap(v.begin(), v.end());
39     while(maxClassHeap.size()){
40         cout<<maxClassHeap.top()<<",";
41         maxClassHeap.pop();
42     }
43     cout<<endl;
44     cout<<"Min heap using cmpFunc to compare int: "<<endl;
45     auto cmpFunction = [](const int a, const int b) { return a > b; };
46     priority_queue<int, vector<int>, decltype(cmpFunction)> minFuncHeap(cmpFunction);
47     for(int i = 0; i < v.size(); ++i) minFuncHeap.push(v[i]);
48     while(minFuncHeap.size()){
49         cout<<minFuncHeap.top()<<",";
50         minFuncHeap.pop();
51     }
52     cout<<endl;
53     return 0;
54 }
View Code

输出如下:

技术分享
 1 Sorted ascending vector using less<int>: 
 2 10,20,50,60,
 3 Min heap using greater<int>: 
 4 10,20,50,60,
 5 Unsorted pair vector: 
 6 20,19,18,17,16,15,14,13,12,11,
 7 Sorted ascending pair vector: 
 8 11,12,13,14,15,16,17,18,19,20,
 9 Min heap using greater<pair<int, int>>: 
10 9,8,7,6,5,4,3,2,1,0,
11 Max heap using cmpClass to compare int: 
12 60,50,20,10,
13 Min heap using cmpFunc to compare int: 
14 10,20,50,60,
View Code
  • a more complex usage for funcCmp.
技术分享
1 auto cmp = [&nums1, &nums2](const pair<int, int>& a, const pair<int, int>&b) {
2             return nums1[a.first]+nums2[a.second] > nums1[b.first]+nums2[b.second]; };
3 priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> minHeap(cmp);
View Code

Basics

  1. Access the inner map via the outer map
    auto inner_map = cost_function.find(c0);
    int minCost = inner_map->second.find(c1)->second;

     

 

内置容器的排序规则构造方式