c++自定義排序(總結)
以下全是根據使用經驗得出的個人總結,供大家參考,如果有什麼不對的歡迎指出
首先將需要排序的情況分類
需要排序的型別分為 基本型別(int,float...)和自定義型別
需要用到排序的地方 模板函式(sort,merge,for_each...)和模板類
注:模板函式中需要的比較引數是函式名,而模板類中需要的比較引數是型別名(因為是型別所以只能使用函式物件)
內建函式物件(關係仿函式)
關係仿函式 tmplate<class T> bool equal_to<T> 等於 tmplate<class T> boolnot_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,intv2) { 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