C stl 的sort使用中的坑

2021-08-22 17:55:54 字數 1712 閱讀 1541

stl的sort函式是乙個很有用且高效的排序方法。如果自行新增比較函式,可以很大程度上的擴充套件其功能,使之能靈活的適應各種場景。但是sort在使用過程中存在一些注意事項,如果不加注意,很容易發生bug滿地跑,你卻不知道bug的源頭在**的情況。

1.sort需要迭代器是隨機訪問迭代器。如果使用list容器,可以使用list容器自帶的sort成員函式,而不要使用使用這個泛型演算法的sort。

2.sort的加比較函式的過載版本:sort(begin,end,comp),需要comp編譯時不能被改變符號名。類成員函式無法作為比較函式,但是可以使用比較類或者過載類的比較運算子。一般採用的方法時定義comp為全域性的函式,或者c++ 11可以使用lambda表示式。詳情可以參考[1].

3.comp函式的書寫需要注意嚴格弱序規則。所謂嚴格弱序規則,簡單來講就是只用乙個嚴格弱序就能區分兩個關鍵字的大小。比如 x大於y可以用y推廣到比較函式,嚴格弱序的規則可以表示為:

兩個關鍵字不能同時「嚴格弱序」於對方

如果a「嚴格弱序」於b,且b「嚴格弱序」於c,則a必須「嚴格弱序」於c

如果存在兩個關鍵字,任何乙個都不「嚴格弱序」於另乙個,則這兩個關鍵字是相等的。(參考[2])

舉個例子:

#include #include #include bool comp(int x1, int x2) 

int main()

為了清楚顯示true和false,我在**中寫出了。這裡可以驗證一下這裡的判斷是否屬於嚴格弱序。如果有陣列vec[0]=5,vec[1]=8,vec[2]=5。

可以看出對於vec[1] > vec[0]成立 和vec[0] > vec[1]成立,顯然只會有vec[1] > vec[0]成立(同理vec[1]和vec[2])。

第二個條件這個情況下不存在,但是乙個5改為4,就可以發現是滿足的。

vec[0] > vec[2]不成立,vec[2] > vec[0] 不成立,所以vec[0] == vec[2]。

但是 >=就不對了,因為不滿足第乙個種情況,5和5同時滿足vec[0] >= vec[2]成立,vec[2] >= vec[0]成立。(注意這裡成立為返回true,不成立為返回false,不理解這裡,下文就無法理解)

這時候仔細思考下,是不是》=就不能放在比較函式中用來判斷了嗎?看下修改後的例子:

bool comp(int x1, int x2)
這個時候修改 >為 >= ,同時置換false和true的位置,再上機編譯,輸入5,8 ,5又能通過了(只是這裡排序方式顛倒了)。主要問題就在於上文中的成立和不成立的判斷。true代表成立,false代表不成立。

對5,8,5不滿足的上文的第1個條件,在這種情況下再分析(這裡成功轉變為上文中第3條):

可以看出對於vec[0] > =vec[2]返回false(不成立)的情況 和vec[0] > = vec[2]返回false(不成立)的情況,顯然只會有vec[1] == vec[0]成立(返回ture)。

最後,如果被成功繞暈了。這裡經驗性的結論就是,不要在相等的情況下時候返回true。在》號時,5,5比較返回false。

在》= 時候,5和5比較,5>= 5,但是還是返回false。

最最後,如果在出現比較函式出錯的情況,加上或者減去乙個等號往往就會成功。

[1]原創位址,文章中為參考位址)

[2]

C STL中sort用法介紹

前情提要 0 要使用sort,首先需要包含標頭檔案 algorithm 1 sort函式可以指定兩個引數,也可以指定三個引數。1 第乙個是要排序的陣列的起始位址。2 第二個是結束的位址 最後一位要排序元素的後一位的位址 3 第三個引數是排序的方法,可以是從大到小也可是從小到大,還可以不寫第三個引數,...

C STL庫中sort函式用法

首先sort函式因為它使用的排序方法是類似於快排的方法,時間複雜度為n log2 n 執行效率較高。所以一般資料量很大的資料排序都可以用它來進行。1 sort 函式的標頭檔案為 include 2 sort函式有三個引數 第乙個是要排序的陣列的起始位址。第二個是結束位址 最後一位要排序的位址 第三個...

C STL之sort的用法總結

sort用法一 對於基本型別的陣列大小從小到大排序 sort 陣列名 n1,陣列名 n2 n1和n2都是int型別的表示式,可以包含變數 如果n1 0,則 n1可以不寫 將陣列中下表範圍為 n1,n2 的元素從小到大排序。下標n2不在排序範圍內。sort用法二 對於元素型別為t的基本型別陣列大小從大...