關於C++中定義比擬函數的三種辦法小結。本站提示廣大學習愛好者:(關於C++中定義比擬函數的三種辦法小結)文章只能為提供參考,不一定能成為您想要的結果。以下是關於C++中定義比擬函數的三種辦法小結正文
C++編程優與Pascal的緣由之一是C++中存在STL(規范模板庫)。STL存在很多有用的辦法。
C++模板庫中的許多辦法都需求相關參數有序,例如Sort()。顯然,假如你想對一個集合停止排序,你必需要知道集合中的對象,那個在前那個在後。因而,學會如何定義比擬辦法是十分重要的。
C++模板庫的許多容器需求相關類型有序,例如set<T> 和priority_queue<T>。
這篇文章旨在通知大家如何為一個類定義一個排序辦法,以便在STL容器或許辦法中運用。 作為一個C++順序員,你應該知道這些辦法。
如何定義排序?
簡而言之,為一個類定義排序,我們就可以知道類的恣意兩個對象在排序的進程中誰在前誰在後。我們可以用一個辦法來完成,這個辦法前往一個bool值表示誰排在後面。顯然,我們希望完成一個相似,f(x,y),這種方式的辦法。它接納同一類型的對象作為兩個參數,前往值則標明誰會呈現在誰後面。
嚴厲弱序化
簡直一切的辦法或容器都需求排序來滿足數學意義上的規范嚴厲弱序化,否則這些辦法或容器的行為將不可預知。
假定f(x,y)是一個比擬函數。 假如該函數滿足如下條件則它是嚴厲弱序化的。
1.f(x,x) = false;
2. if f(x,y) then !f(y,x)
3.if f(x,y) and f(y,z) then f(x,z)
4. if !f(x,y)&&!f(y,x) then x==y; if x==y and y==z then x==z;
看上去有點暈乎,不過不必擔憂,只需你的比擬辦法可以滿足對相等元素永遠前往false,那你的辦法就滿足要求了。
三種完成方式:
1. 定義 < 操作符。
運用這種辦法可以使我們自定義的類可以取得與生俱來的排序才能。例如,假如有如下類:
struct Edge { int from,to ,weight; };
由於要完成Kruskai算法,你希望圖中的一切邊根據權重按降序陳列。 像這樣來定義 operator<:
struct Edge { int from,to ,weight; bool operator <(Edge other) const { return weight>other.weight; } };
你定義的辦法必需依照如下辦法聲明:
bool operator< (T other) const
留意: const關鍵字是必需的。
假如你不喜歡這種方式,比方,明明是要比擬兩個對象,辦法卻只要一個參數。你可以選擇如下方式:
struct Edge { int from,to weight; friend bool operator<(Edge a,Edge b) { return a.weight>b.weight; } };
STL的pair<T1,T2>就具有與生俱來的排序才能。兩個pair對象的比擬這樣的:先比擬第一個參數,假如第一個參數相反再比擬第二個參數。
一切內置類型都具有與生俱來的排序才能,這是由編譯器賦予的。
2. 自定義排序辦法。
運用這種方式經常用在如下情形:
a.比擬內置類型
b.不能修正需求比擬的類型
c.除了類型自定義的比擬方式以外的比擬辦法
復雜來說,一個比擬辦法接納兩個同類型的對象作為參數並且前往一個bool值,原型如下:
bool name(T a,T b);
3. 重載()操作符
我們可以將比擬函數作為STL容器結構函數的第一個參數,並且把函數類型作為模板參數。例如:
set<int,bool (*)(int,int)> s(cmp);
這樣做或多或少會讓人隱晦。那我們就來看看如何運用仿函數來消弭你的疑惑吧。
我們需求定義一個新的類偏重載()操作符。
vector<int> occurrences; struct cmp { bool operator()(int a, int b) { return occurrences[a] < occurrences[b]; } };
如今我們就可以把這個類作為模板參數傳遞給STL容器了。
set<int, cmp> s; priority_queue<int, vector<int>, cmp> pq;
STL也有一些內置的仿函數,例如less<T>,greater<T>等。
仿函數可以經過初始化然後像普通函數一樣運用。最復雜的就是在仿函數前面加上()。
sort(data.begin(), data.end(), greater<int>());
以上就是為大家帶來的關於C++中定義比擬函數的三種辦法小結全部內容了,希望大家多多支持~