2011-08-18 77 views
6

說我有一個「信息」類,它將人的姓名和年齡存儲在向量中。在C++中對象的向量排序

所以......

class Information { 

private: 
int age; 
string name; 

//etc, etc... 
}; 

我將如何排序按升序/向量相對於年齡的遞減順序?

我相信你會用這樣的東西。

sort(listOfPeople.begin(), listOfPeople.end(), greater<Information>()); 

listOfPeople將是矢量。

任何幫助將不勝感激。

回答

6

如果你想他們年齡不降序排序,其中一個辦法是定義一個函子進行比較:

class CompareInformations { 
    public: 
    // after making CompareInformations a friend class to Information... 
    operator(const Information& rhs, const Information& lhs) { 
     return rhs.age < lhs.age; 
    } 
}; 

然後做你的排序:

sort(listOfPeople.begin(), listOfPeople.end(), CompareInformations()); 

你也可以超載operator<爲您的類,並沒有比較對象做:

// inside your class 
bool operator <(const Information& rhs) { 
    return age < rhs.age; 
} 

在排序:

sort(listOfPeople.begin(), listOfPeople.end()); 

上面的例子假設你想在非降排序(幾乎上升,但並不完全)的順序。要做非升序 order,只需將所有的<改爲>即可。

+0

通過使CompareInformations成爲信息的朋友類是什麼意思? – user432584920684

+0

@Vincent像你一樣,'age'是一個私有變量,'CompareInformations'類訪問這個變量。這會給你一個錯誤,因爲這是不允許的。但是,如果您在'Information'的定義中放置了'friend class CompareInformations',則會讓'CompareInformations'訪問該類的私有成員。或者你可以用'rhs.getAge()'或者你定義的任何訪問器來替換'rhs.age'和東西。 –

+0

是的,我用rhs.getAge()。我嘗試過,但是在嘗試編譯時遇到以下錯誤消息。 錯誤:傳遞'const Information'作爲'int'參數的'int Information :: getAge()'丟棄限定符testone.cpp – user432584920684

3

您需要創建一個比較函數或函子類,如果第一個應該在第二個之前進行排序,則需要兩個Information引用並返回true

下面將排序從舊到新的:

bool CompareAges(const Information & left, const Information & right) 
{ 
    return left.age > right.age; 
} 

std::sort(listOfPeople.begin(), listOfPeople.end(), CompareAges); 

要選擇是否排序升序或降序,你可以有不同的比較功能的兩個不同的調用sort,或者你可以創建一個仿函數類有一個標誌確定項目應該如何排序。

struct CompareAgesUpOrDown 
{ 
    CompareAgesUpOrDown(bool bDown) : m_bDown(bDown) {} 
    bool operator() (const Information & left, const Information & right) 
    { 
     if (m_bDown) 
      return left.age < right.age; 
     else 
      return left.age > right.age; 
    } 
    bool m_bDown; 
}; 

bool bDown = ...; 
std::sort(std::sort(listOfPeople.begin(), listOfPeople.end(), CompareAgesUpOrDown(bDown)); 
+0

我不知道如果我正確地做,但試圖執行第一個代碼塊試圖compile.testone.cpp時給我以下輸出:27:錯誤:作爲'this'參數傳遞'const信息' 'int Information :: getAge()'丟棄限定符 testone.cpp:27:error:將'const Information'作爲'int'參數傳遞給'int Information :: getAge()'丟棄限定符 – user432584920684

+0

@Vincent mark'getAge'作爲'const' –

+0

對不起,我對此很新。如何將getAge標記爲const? – user432584920684

0

我會重載operator <,然後使用更大的排序。更重要的是指rhs < lhs。然後,您使用排序sort(listOfPeople.begin(), listOfPeople.end(), greater<Information>());

如果您決定添加operator<類將與std::set並作爲std::map除了允許排序的關鍵發揮很好。

class Information { 

private: 
int age; 
string name; 

friend bool operator< (Information const& lhs, Information const& rhs){ 
    return lhs.age < rhs.age; 
} 

//etc, etc... 
}; 
+0

任何理由這是一個朋友功能,而不是一個成員函數? –

+0

習慣的力量。我通常處理算術類型,並希望免費函數從轉換中受益。 – Flame

1

您需要有一個比較函數或對象才能使用該類型。看看sort page at cplusplus.com的例子和信息。

下面是使用的比較功能的完整的例子:

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 

class Information { 
public: 
    Information(int age, std::string name) : m_age(age), m_name(name) {} 
    int age() const { return m_age; } 
    std::string name() const { return m_name; } 
private: 
    int m_age; 
    std::string m_name; 

    friend bool sortInformationByAgeAscending(const Information& lhs, 
              const Information& rhs);  
    friend bool sortInformationByAgeDescending(const Information& lhs, 
              const Information& rhs); 
}; 

bool sortInformationByAgeAscending(const Information& lhs, 
            const Information& rhs) { 
    return lhs.m_age < rhs.m_age; 
} 

bool sortInformationByAgeDescending(const Information& lhs, 
            const Information& rhs) { 
    return lhs.m_age > rhs.m_age; 
} 
int main (int argc, const char * argv[]) 
{ 
    std::vector<Information> info; 
    info.push_back(Information(1, "Bill")); 
    info.push_back(Information(5, "Ann")); 
    info.push_back(Information(2, "Sue")); 

    std::sort(info.begin(), info.end(), sortInformationByAgeAscending); 

    std::cout << info.at(0).age() << ": " << info.at(0).name() << std::endl; 
    std::cout << info.at(1).age() << ": " << info.at(1).name() << std::endl; 
    std::cout << info.at(2).age() << ": " << info.at(2).name() << std::endl; 

    return 0; 
} 
+0

努力+1(長度) –

2

其他人已經所示的C++ 98/03的解決方案。在C++ 11,你可能想使用lambda你比較,而不是:

// ascending age: 
std::sort(people.begin(), people.end(), 
      [](person const &a, person const &b) { return a.age < b.age; }); 

// descending age: 
std::sort(people.begin(), people.end(), 
      [](person const &a, person const &b) { return b.age < a.age; }); 

而且,在情況下,它碰巧出現:

// ascending name: 
std::sort(people.begin(), people.end(), 
      [](person const &a, person const &b) { return a.name < b.name; }); 

// descending name: 
std::sort(people.begin(), people.end(), 
      [](person const &a, person const &b) { return b.name < a.name; }); 

IMO,Information是過於籠統的名稱,所以我將它更改爲person。相反,listOfPeople過分強調形式而不是內容(更糟糕的是,這顯然是錯誤的,因爲你真的有一個人的矢量,而不是一個列表)。國際海事組織,在編程方面,通常只使用list來引用鏈表,而不是一般的線性數據結構。

+0

謝謝,我會記住你的提示。 只是一個問題,我假設你不需要bool比較函數,如果你這樣實現它?當我回家時,我會嘗試這些代碼。 – user432584920684

+0

@Vincent:是的。使用lambda可以指定內聯比較代碼,而不是單獨使用。 FWIW,如果您通常使用一種排序,您可能希望將其放入類「operator <」中,並且只顯式指定其他情況的順序。 –