以下全是根据使用经验得出的个人总结,供大家参考,如果有什么不对的欢迎指出
首先将需要排序的情况分类
需要排序的类型分为 基本类型(int,float...)和自定义类型
需要用到排序的地方 模板函数(sort,merge,for_each...)和模板类
注:模板函数中需要的比较参数是函数名,而模板类中需要的比较参数是类型名(因为是类型所以只能使用函数对象)
内置函数对象(关系仿函数)
关系仿函数 tmplate<class T> bool equal_to<T> 等于 tmplate<class T> bool not_equal_to<T> 不等于 tmplate<class T> bool gerater<T> 大于 tmplate<class T> bool gerater_equal<T> 大于等于 tmplate<class T> bool less<T> 小于 tmplate<class T> bool less_equal<T> 小于等于
其中最常用的就是下面这两个
tmplate<class T> bool gerater<T> 大于
tmplate<class T> bool less<T> 小于
less<T>是各种模板函数和模板类的默认比较函数,从小到大升序排序
适用范围:
通常内置关系仿函数用于基本类型的比较,主要是用起来比较方便
模板函数和模板类都适用,但是参数的形式是有区别的
比如用sort()函数对数组排序 (模板函数)
bool cmp(int v1,int v2) { return v1>v2; } int s[]={15,17,5,7}; int n=4; sort(s,s+n,cmp); //sort(s,s+n,greater<int>());
比较参数为函数名,实际上自定义比较函数cmp的作用根greater<T>是一样的
但是为什么上面调用的是cmp不加括号的,而下面调用的greater<int>()却是加括号的呢?
其实很简单,上面提到过模板函数需要的比较参数是函数名,而greater<T>就是一个模板类,在后面加个括号就相当于生成一个匿名的对象,因为其内部重载了小括号所以又称之为函数对象或者仿函数,其对象加括号可以像函数一样来使用,所以也可以把那个对象(匿名)看作一个函数名。ps:不是没有名字吗怎么还能当作函数名?这个是实参,形参有名字就行了!!
用set存储元素 (模板类)
class cmp{ public: bool operator()(int v1,int v2){ return v1>v2; } }; set<int,cmp>set={15,17,7,5};
// set<int,greater<int>>set={15,17,7,5}; // 17 15 7 5
模板类中需要的比较参数是类型名,所以只要将类型名传入就行了
自定义函数对象(仿函数)
例子上面已经写了
适用范围:
适用于所有类型(基本类型和自定义类型)
适用于所有情况(模板函数和模板类),只是在调用时注意模板函数和模板类所需要的参数形式不同!!(第n次重复)
万金油了属于是,任何情况都可以用
自定义比较函数cmp()
例子在上面已经写了
适用范围:
适用于所有类型 (基本类型和自定义类型),毕竟参数是自己写的嘛
适用于模板函数(参数需要函数名)不适用于模板类(参数需要类型名)
重载'<'
如果要重载比较符来改变排序规则,只能重载'<'而不能重载'>'
其实要理解也简单,主要是c++中的默认排序就是 less('<'),你如果重载'>' 函数和类内部压根没用'>',所以重载了也没用,哪怕最后'<'执行的排序结果是从大到小那也只能重载'<'
适用范围:
适用于自定义类型,不适用于基本类型,如果问什么,那我只能说2不可能小于1!
适用于所有情况 (模板函数和模板类),对于重载过'<'的类型,因为函数和类里面调用的就是'<'所以此时并不需要显式的传参
#include <bits/stdc++.h> using namespace std; struct Point { int x, y; Point() {} Point(int a, int b) : x(a), y(b) {} }; //升序 bool operator<(const Point &p1, const Point &p2) { if (p1.x == p2.x) return p1.y < p2.y; else return p1.x < p2.x; } //降序 /* bool operator<(const Point &p1, const Point &p2) { if (p1.x == p2.x) return p1.y > p2.y; else return p1.x > p2.x; } */ void test01() { set<Point> set = {{7, 5}, {5, 7}, {17, 15}, {15, 17}}; vector<Point> v = {{7, 5}, {5, 7}, {17, 15}, {15, 17}}; cout << "set:" << endl; for (auto i : set) cout << i.x << ' ' << i.y << endl; cout << "vector:" << endl; sort(v.begin(), v.end());//排序 for (auto i : v) cout << i.x << ' ' << i.y << endl; } int main() { test01(); return 0; }
执行结果:
有任何问题欢迎指出!
讲的不是很详细,不懂dd