STL设置自定义排序

时间:2013-11-14 13:40:40

标签: c++ debugging sorting stl set

当我意识到它是impossible to resort a set and i had to create a new set and have a custom sort function to resort it时,我试图求助于一套。我researched online并试图实现我自己的自定义排序功能,但我不确定如何去做它

这是我的班级

class Point2D
{
 public:

           int getX() const;
           int getY() const;

           void setX(int);
           void setY(int);


          bool operator < ( const Point2D& x2) const
          {
            if ( x != x2.x)
            {
            return x < x2.x;
            }
            if ( y != x2.y)
            {
              return y < x2.y;
            }
          };

 protected:

             int x;
             int y;


};

目前根据x值后跟y值进行排序,我想根据

求助
  

y值后跟x值

因此我实现了这种自定义排序

bool p2d_sortby_y(Point2D& ptd1 , Point2D& ptd2) //custom sort function
{
    if ( ptd1.getY() != ptd2.getY())
    {
        return ptd1.getY() < ptd2.getY();
    }
  if ( ptd1.getX() != ptd2.getX() )
    {
        return ptd1.getX() < ptd2.getX();
    }

    return false;
}

这是我如何尝试使用该集的示例代码,

#include <iostream>
#include <string>
#include <fstream>
#include <set>
#include <cmath>
using namespace std;
class Point2D
{
 public:

           int getX() const;
           int getY() const;

           void setX(int);
           void setY(int);


          bool operator < ( const Point2D& x2) const
          {
            if ( x != x2.x)
            {
            return x < x2.x;
            }
            if ( y != x2.y)
            {
              return y < x2.y;
            }
          };

 protected:

             int x;
             int y;


};

bool p2d_sortby_y(Point2D& ptd1 , Point2D& ptd2) //custom sort function
{
    if ( ptd1.getY() != ptd2.getY())
    {
        return ptd1.getY() < ptd2.getY();
    }
  if ( ptd1.getX() != ptd2.getX() )
    {
        return ptd1.getX() < ptd2.getX();
    }

    return false;
}



int main()
{
    set<Point2D> p2d_set;

    Point2D p2d;

    p2d.setX(1);
    p2d.setY(3);

    p2d_set.insert(p2d);

    p2d.setX(3);
    p2d.setY(2);

    p2d_set.insert(p2d);

    set<Point2D>::iterator p2 = p2d_set.begin();

   while ( p2 != p2d_set.end() )
   { 
     cout<<p2->getX()
         <<" "
         <<p2->getY()
         <<endl;
     p2++;
   }


   set<Point2D,p2d_sortby_y> p2d_set2 = p2d_set; // i am unsure of how to implement the custom sort function here





}



int Point2D::getX() const
{
   return x;
}

int Point2D::getY() const
{
   return y;
}
void Point2D::setX(int x1)
{
   x = x1;
}

void Point2D::setY(int y1)
{
 y = y1;  ;
}

有人可以帮助我谢谢吗?

4 个答案:

答案 0 :(得分:5)

这将是一种更简单的方法:

#include <tuple>

struct SortByYX
{
  bool operator ()(const Point2D& lhs, const Point2D& rhs) const
  {
    return std::tie(lhs.y, lhs.x) < std::tie(rhs.y, rhs.x);
  }
};

然后

set<Point2D, SortByYX> p2d_set2(p2d_set.begin(), p2d_set.end());

修改std::tie需要C ++ 11支持,但如果您没有,则可以使用std::tr1::tie中的<tr1/tuple>或{{ 1}}如果你没有TR1。

答案 1 :(得分:0)

set<Point2D, p2d_sortby_y>中,第二个参数p2d_sortby_y未命名类型。

struct point_odered_by_y
{
    bool operator()(const Point2D& ptd1, const Point2D& ptd2) const
    {
        /* .. */
    }
};



typedef std::set<Point2D, point_odered_by_y> pointset;
pointset s(begin(p2d_set), end(p2d_set));

答案 2 :(得分:0)

通常最好定义一个functor类来指定排序,而不是一个函数;这样,您可以将其指定为模板参数:

struct p2d_sortby_y {
    bool operator()(Point2D x, Point2D y) {return whatever;}
};

这必须通过值或const引用(不是非const引用,因为你的参数)来使用它的参数,以便在常量集成员上使用。

您不能直接从不同类型的集合初始化新集合,但您可以从其范围初始化它:

set<Point2D,p2d_sortby_y> p2d_set2(p2d_set.begin(), p2d_set.end());

答案 3 :(得分:0)

您的两个集合具有不同的类型(比较函数是类型定义的一部分)。

由于std::set没有为不同的比较函数提供构造函数或赋值运算符,因此必须使用迭代器对初始化新集合到第一个集合,或者std::copy初始化元素。“ p>

那是:

set<Point2D,p2d_sortby_y> p2d_set2 { std::begin(p2d_set), std::end(p2d_set) };

set<Point2D,p2d_sortby_y> p2d_set2;
std::copy(std::begin(p2d_set), std::end(p2d_set), std::inserter(p2d_set2));