2011-12-30 109 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; 
}