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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM