通过坐标值排序矢量与3D点 - 语法

时间:2010-02-20 08:47:40

标签: c++

我想对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。还有另一种方法可以解决这个问题吗?

感谢

5 个答案:

答案 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个双打组成的点数”。

我认为最好的方法是:

  1. 将积分存储为一些Point3D类而非一对双打
  2. 为Point3D
  3. 定义less less运算符
  4. 只需调用std :: sort(points_vec.begin(),points_vec.end());
  5. 如果您想要以不同的方式对它们进行排序,那么当您使用排序仿函数并使用运算符()为不同目的创建不同的仿函数时。

答案 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

时,请不要使用parens
std::sort(points_vec.begin(), points_vec.end(), compare_points );