问题是关于使用STL算法类中的函数std::vector<myclass>
对sort
进行排序
标准方式是:sort(v.begin(), v.end(), &myfunct)
其中myfunct
是:
bool myfunct( myclass first, myclass second ) {
if (first.value < second.value)
return true;
else return false;
}
上述方法需要不止一行。我很好奇如何在一行中做到这一点。是否有可能定义比较排序函数中的myclass对象的函数?可能以某种方式使用此(a < b) ? a : b
。我记得在C#中有这样的东西,但是我忘了怎么称呼它。是否可以用C ++做。
答案 0 :(得分: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,我认为你需要一个函数对象,因为没有任何东西可以将你的类投射到你想要比较的值。
顺便说一句,你肯定想通过引用你的比较函数传递除了最简单的对象之外的所有东西。答案 1 :(得分:2)
您可以使用boost::lambda
和boost::lambda::bind
(使用提升lambda占位符)
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个值。代码的绑定部分只从被比较的每个结构a
中选择变量struct 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
答案 2 :(得分:1)
为什么不将矢量复制到集合中:
std::copy(v.begin(),v.end(),std::inserter(s,s.end()));
现在,集合中的元素按升序排序,并立即使用set。
答案 3 :(得分:0)
对sort()的单行调用: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;
}