以下全是根據使用經驗得出的個人總結,供大家參考,如果有什么不對的歡迎指出
首先將需要排序的情況分類
需要排序的類型分為 基本類型(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