我想对points_vec向量进行排序,如下面的伪代码所示。我想通过像x或y或z
这样的坐标值对这个向量进行排序class A{
std:vector<double*> points_vec;
void doSomething();
}
然后,在方法A::doSomething,
中,我想要对此向量进行排序:
void A::doSomething() {
std::sort(points_vec.begin(), points_vec.end(), sortPoints());
}
有人可以告诉我sortPoints()
方法的语法。我最好希望它是A类的方法。this post创建一个struct
来执行此操作,不确定是否我应该在课堂上创建一个类似的struct
。还有另一种方法可以解决这个问题吗?
感谢
答案 0 :(得分:5)
最简单的方法是提供一个由sort
算法用来比较两个值的仿函数。你可以这样写:
struct Compare
{
bool operator()(double* first, double* second) const
{
//Compare points here
}
};
并使用如下:
std::sort(p.begin(), p.end(), Compare());
编辑OP评论:是的,此示例代码编译良好:
class A
{
public:
struct c
{
bool operator()(int a, int b) const
{
return a < b;
}
};
};
int main()
{
std::vector<int> a1;
a1.push_back(2);
a1.push_back(1);
std::sort(a1.begin(), a1.end(), A::c());
return 0;
}
答案 1 :(得分:5)
您有两种排序选项:将函数/仿函数传递给sort
或为您的班级定义operator<
。现在,您的类A
似乎更像是一组坐标的包装器。所以,为你的坐标创建另一个类。
struct Point {
double x_, y_, z_;
Point(double x, double y, double z) : x_(x), y_(y), z_(z) {}
// just an example, you can refine the following as much as you need
bool operator<(Point const& other) {
return x < other.x;
}
};
bool sortOnY(Point const& l, Point const& r) const {
return l.y < r.y;
}
class A {
std::vector<Point> pts_;
void doSomething() {
sort(pts_.begin(), pts_.end());
}
// if sorting on y is also required, you will need
// to use a custom comparator which can be either
// a functor or a function
void doSomeOtherThing() {
sort(pts_.begin(), pts_.end(), sortOnY);
}
};
答案 2 :(得分:2)
首先 - 你所拥有的将打破你所有的分数 - 因为你将按单个双打排序而不是“由3个双打组成的点数”。
我认为最好的方法是:
如果您想要以不同的方式对它们进行排序,那么当您使用排序仿函数并使用运算符()为不同目的创建不同的仿函数时。
答案 3 :(得分:2)
如果不提及Boost.Bind:
,我认为这个帖子不会完整struct Point3D {
double x, y;
Point3D(double x=0., double y=0.) : x(x), y(y) {
}
};
int main() {
std::vector<Point3D> points;
points.push_back(Point3D(-1., 2.));
points.push_back(Point3D( 2., -1.));
points.push_back(Point3D(-2., 0.));
using boost::bind;
std::sort(points.begin(), points.end(),
bind(&Point3D::x, _1) < bind(&Point3D::x, _2));
// points sorted by x coord
std::sort(points.begin(), points.end(),
bind(&Point3D::y, _1) < bind(&Point3D::y, _2));
// points sorted by y coord
}
多么羞耻std::tr1::bind
不支持这一点。但是,当然,使用C ++ 0x编译器,您将能够执行此操作:
std::sort(points.begin(), points.end(),
[](Point3D const & a, Point3D const & b) { return a.x < b.x; });
答案 4 :(得分:1)
如果要按x 或 y 或 z排序,则这三种功能不同。要排序的坐标是真正来自std::sort
的额外信息。你需要有一个对象来传递它。
struct coord_comparison {
int coord_id; // <= critical information
bool operator()( double (*l)[3], double (*r)[3] ) {
return (*l)[ coord_id ] < (*r)[ coord_id ];
}
coord_comparison( int id ) { coord_id = id; }
};
在您的类或外部创建此结构,但它必须是结构而不是自由函数,并且operator()
不能是静态的。拨打:
std::sort(points_vec.begin(), points_vec.end(), compare_points( 1 /*for y*/) );
一次按所有3个坐标排序:
你有
std:vector<double*> points_vec;
我将假设double*
指向3个坐标的数组。这更清洁:
std:vector<double(*)[3]> points_vec;
std::sort
的第三个参数是一个比较两个序列对象的仿函数:
bool compare_coords( double(*l)[3], double(*r)[3] ) {
幸运的是,std::less
已经为您编码了比较两个序列:
return std::less( *l, *l + ( sizeof *l/sizeof **l ), r );
(也许我做了比获得数组大小所需的更多工作)
return std::less( *l, *l + 3, r );
}
这个函数在课外可能很有用,所以我会把它变成一个自由函数。如果要留在课堂内,你需要让它static
。
最后,在将函数传递给std::sort
:
std::sort(points_vec.begin(), points_vec.end(), compare_points );