2013-03-12 103 views
1

下面的函數是我的比較函數。在直接比較兩個字符成功分配數組時,使用std :: string compare函數不會。排序比較函數奇怪行爲

int compare (student a, student b) { 
    return a.name.compare(b.name); 
    return a.name[0] < b.name[0]; 
} 

呼叫

sort(data.begin(), data.end(), compare); 

當數據被定義爲vector <student> data;

你有任何想法,那爲什麼的std ::比較不排序呢? PS:std :: compare比較反轉位置的結果,例如,阿蘭,理查德,拜倫,莎拉 - >莎拉,拜倫,理查德,阿蘭。

+1

這不是特別清楚。你能否添加一些具體的測試代碼(即我們可以編譯和運行的10行程序,可能在http://ideone.com中)來演示什麼不起作用? – 2013-03-12 22:17:35

+0

其他人對'student'及其成員的類型decl有遠程興趣嗎? (並注意:你的第二個回報是毫無意義的)。 – WhozCraig 2013-03-12 22:17:46

+1

@WhozCraig No ... – 2013-03-12 22:18:09

回答

6

std::string::compare返回一個int您打算與0比較以給出實際的排序順序。例如,要檢查是否a.name小於b.name(根據compare給出的順序),你可以這樣寫:

return a.name.compare(b.name) < 0; 

是當前已寫它會返回true任何不平等的字符串的方式,這是不根據std::sort的要求,有效的strict weak ordering

沒有充分的理由在這裏使用compare所有的,因爲std::stringoperator<,讓兩個字符串的等效排序:

return a.name < b.name; 
1

排序預計其比較的行爲類似於運營商<,而STD :: string :: compare的行爲與here相同。

1

您要退回的int其中std::sort認爲是「相同」或「不相同」。您應該返回此:

return a.name.compare(b.name) < 0; 

,並更改返回類型bool

但是,你有沒有考慮過這個來代替:

class student 
{ 
public: 
    ... members ... 

    bool operator <(const student& s) const 
    { 
     return name < s.name; 
    } 

private: 
    std::string name; 
}; 

,擺脫你想自定義比較以完全製造。通過這種方式,您可以使用std::sort(students.begin(), students.end())對一批學生進行排序,因爲在排序時進行比較時,默認比較鍵std::less<YourType>會調用您的操作員。

+0

或簡單的'a.name 2013-03-12 22:22:07

+1

@SethCarnegie是的,是的,他似乎固定使用該功能。不知道爲什麼。爲什麼不根本不使用比較器*? std :: less <>完全符合你的要求。 – WhozCraig 2013-03-12 22:22:54

+1

只有'學生'有一個'操作符<'。 – 2013-03-12 22:23:39

2

請仔細閱讀std::sort reference at cppreference.com;它清楚地解釋了比較函數應該返回一個bool,表示第一個參數小於第二個參數。

在這種情況下,你會這樣稱呼它:

std::sort(data.begin(), data.end(), [](student const& a, student const& b) { 
    return a.name < b.name; 
}) 

那麼,是什麼在你的代碼發生了什麼?如果name s相等,則compare返回0,該值被轉換爲false。否則,您將得到一個非零整數,該整數將被轉換爲true。由於std::sort中的排序算法沒有完全規定,所以我們不能說您爲什麼要精確地獲得某個順序,但本質上,它是隨機產生的對象(僞)。

那麼,你應該定義一個compare函數嗎?恕我直言,不。定義一些基本類型是很容易的,但據我所知,它並不真正出現在任何算法中。這是一個C-ISM,不幸的是,C++保留了它。如果合適,定義一個嚴格的弱排序而不是使用operator<,或者只是在需要時定義比較器。