C++ STL集合排序

C++ STL 集合排序

map<key,value>set<key>的内置键值比较函数排序

// 按照键值升序排列
map<string,int,less<string>> map1; // 等效map<string,int> map1; 
set<string,less<string>> set1; // 等效set<string>;

// 按照键值降序排列
map<string,int,greater<string>> map1; 
set<string,greater<string>> set1; 

map<key,value>set<key>的自定义比较函数排序

首先定义比较函数,例如:

/***************************************************
 * map key compare
 * include compare string's length
 * 用于排序map的keys,如:"P1","P2","P10",...
 * 用法:
 * (1)map键值排序:map<string,int,cmpByKey> map1;
 * (2set排序: set<string,cmpByKey> set1;
 * (3)vector<string>排序:
 *      #include <algorithm>
 *      vector<string> vec1;
 *      std::sort(vec1.begin(), vec1.end(), cmpByKey());
 ****************************************************/
struct cmpByKey {
    bool operator()(const std::string& lhs, const std::string& rhs) const
    {
        bool ret;
        if (lhs.size() == rhs.size())
            ret = lhs < rhs ? true : false;
        else
            ret = lhs.size() < rhs.size() ? true : false;
        return ret;
    }
};

其次声明使用自定义比较函数的对象

// 使用自定义键值比较函数的map,set对象
map<string,int,cmpByKey> map1;
set<string,cmpByKey> set1;

定义比较函数的”严格弱序化”要求

比较函数必须满足数学意义上的标准严格弱序化,否则这些方法或容器的行为将不可预知。
假设f(x,y)是一个比较函数。 如果该函数满足如下条件则它是严格弱序化的
1. 非自反性(irreflexive):f(x,x) = false;
2. 非对称性(antisymmetric): if f(x,y) then !f(y,x)
3. 可传递性(transitivity): if f(x,y) and f(y,z) then f(x,z)
4. 等效传递性(transitivity of equivalence):
if !f(x,y)&&!f(y,x) then x==y; if x==y and y==z then x==z;

比较方法能够满足对相等元素永远返回false(记住一个准则:永远让比较函数对相同元素返回false),那你的方法就满足要求了。

其实,set容器在判定已有元素a和新插入元素b是否相等时,是这么做的:1)将a作为左操作数,b作为右操作数,调用比较函数,并返回比较值 2)将b作为左操作数,a作为右操作数,再调用一次比较函数,并返回比较值。如果1、2两步的返回值都是false,则认为a、b是相等的,则b不会被插入set容器中;如果1、2两步的返回值都是true,则可能发生未知行为,因此,记住一个准则:永远让比较函数对相同元素返回false。

vector<>集合的排序

定义比较函数同上
使用algorithm中的sort()函数排序

#include <algorithm>
vector<string> vec1;
std::sort(vec1.begin(), vec1.end(), cmpByKey());

附完整示例代码

#include "stdafx.h"
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>

using namespace std;

/***************************************************
 * map key compare(要求严格弱序化,即相等元素,返回false)
 * include compare string's length
 * 用于排序map的keys,如:"P1","P2","P10",...
 * 用法:
 * (1)map键值排序:map<string,int,cmpByKey> map1;
 * (2)set排序: set<string,cmpByKey> set1;
 * (3)vector<string>排序:
 *      #include <algorithm>
 *      vector<string> vec1;
 *      std::sort(vec1.begin(), vec1.end(), cmpByKey());
 ****************************************************/
struct cmpByKey {
    bool operator()(const std::string& lhs, const std::string& rhs) const
    {
        bool ret;
        if (lhs.size() == rhs.size())
            ret = lhs < rhs ? true : false;
        else
            ret = lhs.size() < rhs.size() ? true : false;
        return ret;
    }
};

int main()
{
    cout << "map内置比较函数排序(升序)" << endl;
    map<string, int, less<string>> map1;  // 使用默认系统定义的键值比较函数(升序),等效于map<string, int> map1;
    map1.insert(make_pair("P10", 1));
    map1.insert(make_pair("P2", 2));
    map1.insert(make_pair("P3", 3));
    map1.insert(make_pair("P3", 33)); // 无效
    map1["P4"] = 4;  // 插入key "P4"的value为4
    map1["P4"] = 44;  // 修改key "P4"的value为44
    for (auto it = map1.begin(); it != map1.end(); it++)
    {
        if (next(it) == map1.end()) cout << it->first << "," << it->second << endl;
        else cout << it->first << "," << it->second << " | ";
    } // P10, 1 | P2, 2 | P3, 3 | P4, 44

    cout << "map内置比较函数排序(降序)" << endl;
    map<string, int, greater<string>> map2; // 使用系统定义的键值比较函数(降序)
    map2.insert(make_pair("P10", 1));
    map2.insert(make_pair("P2", 2));
    map2.insert(make_pair("P3", 3));
    for (auto it = map2.begin(); it != map2.end(); it++)
    {
        if (next(it) == map2.end()) cout << it->first << "," << it->second << endl;
        else cout << it->first << "," << it->second << " | ";
    } // P3,3 | P2,2 | P10,1

    cout << "set内置比较函数排序(降序)" << endl;
    set<string, greater<string>> set1;  // 降序(greater),升序(less)
    set1.insert("P10");
    set1.insert("P2");
    set1.insert("P3");
    for (auto it = set1.begin(); it != set1.end(); it++)
    {
        if (next(it) == set1.end()) cout << *it << endl;
        else cout << *it << ",";
    } // P3,P2,P10

    cout << "map自定义比较函数排序" << endl;
    map<string, int, cmpByKey> map3;
    map3.insert(make_pair("P10", 1));
    map3.insert(make_pair("P2", 2));
    map3.insert(make_pair("P3", 3));
    map3.insert(make_pair("P3", 33)); // 无效
    map3["P4"] = 4;  // 插入key "P4"的value为4
    map3["P4"] = 44;  // 修改key "P4"的value为44

    for (auto it = map3.begin(); it != map3.end(); it++)
    {
        if(next(it) == map3.end()) cout << it->first << "," << it->second << endl;
        else cout << it->first << "," << it->second << " | ";
    } // P2,2 | P3,3 | P4,44 | P10,1

    cout << "set自定义比较函数排序" << endl;
    set<string, cmpByKey> set2;
    set2.insert("P10");
    set2.insert("P2");
    set2.insert("P3");
    set2.insert("P3"); // 无效
    for (auto it = set2.begin(); it != set2.end(); it++)
    {
        if (next(it) == set2.end()) cout << *it << endl;
        else cout << *it << ",";
    } // P2,P3,P10

    cout << "vector<>内置比较函数排序(升序)" << endl;
    vector<string> vect1 = { "P10","P2","P3","P2" };
    // std::sort(vect1.begin(), vect1.end(), less<string>()); // 等效默认
    std::sort(vect1.begin(), vect1.end()); // 默认 
    for (auto it = vect1.begin(); it != vect1.end(); it++)
    {
        if (next(it) == vect1.end()) cout << *it << endl;
        else cout << *it << ",";
    } // P10,P2,P2,P3

    cout << "vector<>内置比较函数排序(降序)" << endl;
    vector<string> vect2 = { "P10","P2","P3","P2" };
    std::sort(vect2.begin(), vect2.end(), greater<string>());
    for (auto it = vect2.begin(); it != vect2.end(); it++)
    {
        if (next(it) == vect2.end()) cout << *it << endl;
        else cout << *it << ",";
    } // P3,P2,P2,P10

    cout << "vector<>自定义比较函数排序" << endl;
    vector<string> vect3 = { "P10","P2","P3","P2" };
    std::sort(vect3.begin(), vect3.end(), cmpByKey());
    for (auto it = vect3.begin(); it != vect3.end(); it++)
    {
        if (next(it) == vect3.end()) cout << *it << endl;
        else cout << *it << ",";
    } // P2,P2,P3,P10

    system("pause");
    return 0;
}

参考

C++参考手册 https://zh.cppreference.com/
c++中std::set自定义去重和排序函数 - 南宫轩诺 - 博客园
c++ set容器排序准则 - 每天一点积累

猜你喜欢

转载自blog.csdn.net/weixin_42993054/article/details/81985830