1. 程式人生 > 其它 >c++自定義排序(總結)

c++自定義排序(總結)

以下全是根據使用經驗得出的個人總結,供大家參考,如果有什麼不對的歡迎指出

 

首先將需要排序的情況分類

需要排序的型別分為   基本型別(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