2011-12-30 58 views
1

問題是關於使用STL算法類中的函數sort排序std::vector<myclass>
標準的方法是:sort(v.begin(), v.end(), &myfunct)
其中myfunct是:上述使用STL的排序功能排列std :: vector <myclass>

bool myfunct(myclass first, myclass second) { 
    if (first.value < second.value) 
     return true; 
    else return false; 
} 

方法利用一個以上的線。我很好奇如何在一行中做到這一點。是否可以定義函數來比較排序函數中的myclass對象?可能會以某種方式使用此(a < b) ? a : b。我記得在C#中有這樣的東西,但我忘記了它是如何調用的。在C++中可以做到嗎?

+2

'返回first.value < last.value;' – 2011-12-30 02:41:31

+3

或在myclass中定義'operator <'並調用'sort(v.begin(),v.end())' – James 2011-12-30 02:46:04

+0

如果你使用C++ 11,那麼你可以看看傳遞一個lambda我相信功能。 – 2011-12-30 02:49:06

回答

6

首先,您可以返回first.value < second.value但這並沒有擺脫該功能。在C++ 2011,您可以使用lambda函數:

std::sort(begin, end, [](myclass const& f, myclass const& s){ return f.value < s.value; }); 

沒有C++ 2011我認爲你需要一個函數對象,因爲沒有什麼突出你的類你真正想要的價值比較。

順便說一句,你一定要通過引用你的比較函數來傳遞一切,但最平凡的對象。

+0

的價值?我相信你的意思是參考。 – 2011-12-30 02:58:31

2

你可以使用boost::lambdaboost::lambda::bind(帶升壓拉姆達佔位符)

std::sort(vec.begin(), vec.end(), 
      boost::lambda::bind(&A::a, boost::lambda::_1) 
      < 
      boost::lambda::bind(&A::a, boost::lambda::_2)); 

sort經過2個值的比較功能,所以你需要比較的2個值。代碼的綁定部分只需從struct A中選擇變量a,該變量來自所比較的每個結構(由_1_2引用)。

示例代碼:

#include <iostream> 
#include <algorithm> 
#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/bind.hpp> 
#include <boost/array.hpp> 

struct A 
{ 
    A() : a(0), b(0) {} 
    int a; 
    int b; 
}; 

std::ostream & operator<<(std::ostream & os, A & a) 
{ return os << a.a << ":" << a.b; } 

int main() 
{ 
    boost::array<A,5> vec; 
    std::fill(vec.begin(),vec.end(),A()); 

    vec[0].a = 1; 
    vec[1].a = 3; 
    vec[2].a = 4; 
    vec[3].a = 0; 
    vec[4].a = 2; 

    std::for_each(vec.begin(),vec.end(), std::cout << boost::lambda::_1 << ' '); 
    std::cout << std::endl; 

    std::sort(vec.begin(), vec.end(), 
      boost::lambda::bind(&A::a, boost::lambda::_1) 
      < 
      boost::lambda::bind(&A::a, boost::lambda::_2)); 

    std::for_each(vec.begin(),vec.end(), std::cout << boost::lambda::_1 << ' '); 
    std::cout << std::endl; 
} 

輸出:

1:0 3:0 4:0 0:0 2:0 
0:0 1:0 2:0 3:0 4:0 
1

何不載體複製到一組:

std::copy(v.begin(),v.end(),std::inserter(s,s.end())); 

現在,集合中的元素按升序排序並立即使用集合。

0

甲一個襯裏呼叫進行排序():sort(my_vector_of_class_object.begin(),my_vector_of_class_object.end(),compare);

碼一個的工作演示的 「類的排序矢量對象」 提供如下:

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

using namespace std; 

class my_Class 
{ 

    public: 

    my_Class(int r,int n, int s):rollno(r),name(n),status(s) { } 
    int getRollno() const { return rollno;} 
    int getName() const { return name;} 
    int getStatus() const { return status;} 

    private: 

    int rollno; 
    int name; 
    int status; 
    }; 

    bool compare(const my_Class& x, const my_Class& y) { 
    return x.getRollno() < y.getRollno(); 
} 

int main() 
{ 
    vector<my_Class> my_vector_of_class_object; 
    vector<my_Class>::const_iterator iter; 

    my_Class s1(10,20,30); 
    my_Class s2(40,50,60); 
    my_Class s3(25,85,9); 

    my_Class s4(1,50,2); 
    my_Class s5(90,70,90); 
    my_Class s6(85,85,3); 

    my_Class s7(20,6,89); 
    my_Class s8(70,54,22); 
    my_Class s9(65,22,77); 


    my_vector_of_class_object.push_back(s1); 
    my_vector_of_class_object.push_back(s2); 
    my_vector_of_class_object.push_back(s3); 

    my_vector_of_class_object.push_back(s4); 
    my_vector_of_class_object.push_back(s5); 
    my_vector_of_class_object.push_back(s6); 


    my_vector_of_class_object.push_back(s7); 
    my_vector_of_class_object.push_back(s8); 
    my_vector_of_class_object.push_back(s9); 



    cout <<"Before vector sort \n"; 

    for(iter=my_vector_of_class_object.begin(); iter!=my_vector_of_class_object.end();++iter) 
    std::cout << (*iter).getRollno() << '\t' << (*iter).getName() << '\t' << (*iter).getStatus() << '\n'; 
    cout <<" \n\n"; 

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


    cout <<"After vector sort \n"; 

    for(iter=my_vector_of_class_object.begin(); iter!=my_vector_of_class_object.end();++iter) 
    std::cout << (*iter).getRollno() << '\t' << (*iter).getName() << '\t' << (*iter).getStatus() << '\n'; 

    cout <<" \n\n"; 


return 0; 
}