STL自定义排序函数:sort()函数;priority_queue,set,map等容器排序函数

STL自定义排序函数:sort()函数;priority_queue,set,map等容器排序函数1 sort 函数自定义排序 1 1 sort 模板原型 1 1 1 默认模板 利用 lt 比较 升序排列 template lt class Randlt gt 模板参数为迭代器类型 void sort Randlt first RandIt last

大家好,我是讯享网,很高兴认识大家。

1、sort()函数自定义排序:

1.1、sort()模板原型:
1.1.1、默认模板:利用<比较,升序排列

template <class_Randlt> // 模板参数为迭代器类型 void sort(_Randlt first, _RandIt last); // 参数为起止随机访问迭代器 

讯享网

前提是a、b (_Randlt迭代器指向的对象) 必须可比较大小。元素比较大小是用<进行的,如果表达式a<b的值为 true,则 a 排在 b 前面。

  • a,b为值对象:可直接比较大小
讯享网int myints[] = { 
   32,71,12,45,26,80,53,33}; std::vector<int> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33 // 默认sort模板,使用<排序 std::sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33 
  • a,b为class/struct对象:类中或类外必须重载<比较函数
class A { 
    public: int v1; int v2; A(int n) : v1(n), v2(0) { 
   } // 方式1: bool operator < (const A & a1) const { 
    //重载为 A 的 const 成员函数,重载为非 const 成员函数在某些编译器上会出错 return v1 < a1.v1; } }; // 方式2: bool operator < (const A & a1, const A & a2) { 
    // 类外重载,调用<比较函数时会先在本文件内查找匹配的函数,没有才调用全局空间的<函数 return a1.v1 < a2.v1; } // 默认sort模板,但元素自定义了比较函数 A a2[5] = { 
    13, 12, 9, 8, 16 }; std::sort (a2, a2+5); // 8, 9, 12, 13, 16 

1.1.2、自定义排序模板:

讯享网template <class_Randlt, class Pred> void sort(_Randlt first, _RandIt last, Pred op); // 多了一个比较函数指针或对象 

通过表达式op(a, b)对元素 ab 比较大小,其中Pred op可以是一个函数指针或一个函数对象,如果该表达式的值为 true,则 a 比 b 小。

  • Pred op为函数指针:函数返回值必须为bool量
bool GreaterA(const A & a1, const A & a2) { 
    //v值大的元素作为较小的数 return a1.v1 > a2.v1; } std::sort (a2, a2+5, GreaterA); // 16, 13, 12, 9, 8 按v1的值从大到小排序 
  • Pred op为函数对象:类成员函数返回值必须为bool量
讯享网struct LessA // 自定义排序对象,struct换成class也可以 { 
    bool operator() (const A & a1, const A & a2) { 
    //v的个位数小的元素就作为较小的数 return (a1.v1) < (a2.v1); } }LessA_1; // LessA为对象类型,LessA_1为对象 std::sort (a2, a2+5, LessA_1); // 8, 9, 12, 13, 16 按v1的值从小到大排序 std::sort (a2, a2+5, LessA()); // 8, 9, 12, 13, 16 按v1的值从小到大排序 以上两行结果是一样的,下面一行是先调用了LessA类构造函数构造处函数对象后作为参数使用 

STL中定义了一些函数对象类模板,都位于头文件 functional 中。例如,greater 模板的源代码如下:

template <class T> struct greater { 
    bool operator()(const T& x, const T& y) const{ 
    return x > y; } }; int a[4] = { 
   3, 5, 34, 8}; sort( a, a+4, greater<int>() ); 

1.2、函数对象详细介绍:
如果一个类将()运算符重载为成员函数,这个类就称为函数对象类,这个类的对象就是函数对象。函数对象是一个对象,但是使用的形式看起来像函数调用,实际上也执行了函数调用,因而得名。
推荐学习:C++函数对象及在sort()函数中应用详解

讯享网class CAverage // 函数对象类 { 
    public: double operator()(int a1, int a2, int a3) { 
    //重载()运算符 return (double)(a1 + a2 + a3) / 3; } }; CAverage average // 函数对象 cout << average(3, 2, 3); // 像函数一样调用函数对象 

2、set、map、priority_queue容器自定义排序函数:
2.1、set容器原型:

template < class T, // 键/值类型 class Compare = less<T>, // 比较函数/对象 class Alloc = allocator<T> // set::allocator_type > class set; 

2.1.1、默认排序方式:利用<比较,升序排列


讯享网

讯享网int myints[] = { 
    4,2,7,1,9 }; set<int> mySet(myints, myints + 5); // 1, 2, 4, 7, 9 默认升序排序 

前提是a、b必须可比较大小。元素比较大小是用<进行的,如果表达式a<b的值为 true,则 a 排在 b 前面。
2.1.2、自定义比较函数:
自定义比较函数,可以当参数为结构体时,指定比较的成员变量。

  • Compare为函数指针:函数返回值必须为bool量 复杂不推荐
bool fncomp(int lhs, int rhs) { 
    return lhs<rhs; } // 比较函数 int myints[] = { 
    4,2,7,1,9 }; set<int, bool(*)(int, int)> mySet(fncomp); // 变量声明方式,较复杂 sixth.insert(4); sixth.insert(2); sixth.insert(7); sixth.insert(1); sixth.insert(9); // 1, 2, 4, 7, 9 升序排序 
  • Compare为函数对象类型:类成员函数返回值必须为bool量 简单,推荐
讯享网struct classcomp { 
    // 比较函数对象 bool operator() (const int& lhs, const int& rhs) const { 
    return lhs<rhs; } }; int myints[] = { 
    4,2,7,1,9 }; set<int, classcomp> mySet(myints, myints + 5); // 1, 2, 4, 7, 9 默认升序排序 

2.2、map容器原型:默认也是升序
map使用键进行排序,与set类似,均常用函数对象类型作比较。
在map基础上无法实现按值排序,只能将其转换到其他容器进行。

struct classcomp { 
    bool operator() (const char& lhs, const char& rhs) const { 
    return lhs<rhs; } }; std::map<char, int, classcomp> first; first['a'] = 60; first['c'] = 30; first['b'] = 50; first['d'] = 70; // a, b, c, d 根据键排序 std::map<int, int, std::greater<int>> mi; // 利用函数对象类模板实现降序排序 

2.2.2、map实现按值排序:
将map的键值对放入vector中,利用sort自定义排序。

讯享网bool cmp(const pair<string,int> &p1, const pair<string,int> &p2) { 
    return p1.second > p2.second; // 按值排序 } vector<pair<string,int> > vpr; for(map<string,int>::iterator it = mp.begin(); it != mp.end(); it++){ 
    vpr.push_back(make_pair(it->first,it->second); } sort(vpr.begin(),vpr.end(),cmp); 

2.3、priority_queue容器原型:

template <class T, class Container = vector<T>, class Compare = less<typename Container::value_type> > class priority_queue; 

T:元素的类型。别名为成员类型priority_queue :: value_type。
Container:存储元素的内部基础容器对象的类型,其value_type应为T,别名为成员类型priority_queue :: container_type。
2.3.1、默认排序方式:升序

讯享网int myints[] = { 
    10,60,50,20 }; std::priority_queue<int> second(myints, myints + 4); // 10, 20, 50, 60 

2.3.2、自定义比较函数:

class mycomparison { 
    public: bool operator() (const int& lhs, const int&rhs) const { 
    return (lhs<rhs); } }; std::priority_queue<int, std::vector<int>, std::greater<int> > third(myints, myints + 4); // 60, 50, 20, 10 std::priority_queue<int, std::vector<int>, mycomparison> // 10, 20, 50, 60 

由于模板参数必须顺序赋值,不能调过中间的基本容器参数,所以需要有std::vector<int>,部分。

总结:

1、所有容器、sort()函数默认都是升序排列。
2、可以使用函数指针与函数对象方法进行自定义排序。
3、priority_queue自定义比较函数时需要多家一个基本容器参数vector。

小讯
上一篇 2025-02-27 12:07
下一篇 2025-01-08 18:22

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/46348.html