【问题标题】:C++ sort coordinates stored as object in vectorC ++排序坐标存储为向量中的对象
【发布时间】:2018-05-26 23:00:47
【问题描述】:

在下一个代码中我可以输入一个数字 n 然后我可以输入 n 数字>(x,y) 坐标。

代码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n = 0;
char cr;
class punto{
private:
    int x;
    int y;
public:
    punto();
    ~punto(){}
    void setx(int xn){ x = xn;}
    void sety(int yn) { y = yn; }
    void printcoord();
};
punto::punto()
{
    x=0;
    y=0;
}
void punto:: printcoord()
{
    cout << x << " " << y << endl;
}
int main()
{
    vector<punto> list;
    int x;
        int y;
        punto *p1;
    cin >> n >> cr;
    for(int contador=0; contador<n; contador++){
        if(contador<n){
                cin >> x;
                cin >> y;
                p1=new punto;
                p1->setx(x);
                p1->sety(y);
                list.push_back(*p1);
                cin.get();
            }
        }
    vector<punto>::iterator it;
    if(cr=='x'){
     for ( it = list.begin(); it != list.end(); ++it ) {
            it->printcoord();
     }
    }
    if(cr=='y'){
     for ( it = list.begin(); it != list.end(); ++it ) {
            it->printcoord();
     }
    }
    return 0;
}

这意味着如果我们输入这个:

5 x
1 2
3 4
6 1
2 2
1 1

我们得到这个输出。

1 2
3 4
6 1
2 2
1 1

问题是我不知道如何对 xy 的坐标进行排序。

坐标存储为向量中的对象。

如果我尝试使用 sort 它会说 xy 是非类类型 int

输出应该是:

1 1                    1 1
1 2                    6 1 
2 2     for x          1 2          for y    
3 4                    2 2 
6 1                    3 4

我将不胜感激。

【问题讨论】:

    标签: c++ sorting c++11 object stdvector


    【解决方案1】:

    输出应该是:

    1 1                    1 1
    1 2                    6 1 
    2 2     for x          1 2          for y    
    3 4                    2 2 
    6 1                    3 4
    

    所以基本上你想按照 yx 对对象进行排序。 一种简单的方法是为您的班级定义operator&lt; punto

    bool operator<(const punto& obj)
    {
       return this->y < obj.y;   // this will help you to sort w.r.t Y
    }
    

    现在您可以简单地使用std::sort(),就像您平时使用它一样。

    std::sort(list.begin(), list.end());
    

    为了对 xs 进行排序,您可以编写一个 lambda 函数,该函数将使用您的类的 getter(您需要在类 punto 中定义)。

       // define getters to access the private memebers
       const int& getX()const { return x; }
       const int& getY()const { return y; }
    

    那么你可以这样做:

       // to sort w.r.t Xs: std::sort() with lambda
       std::sort(list.begin(), list.end(),[](const punto& lhs, const punto& rhs)->bool
                                           {  return lhs.getX() < rhs.getX(); });
    

    SEE OUTPUT HERE


    但是,我不明白您为什么要创建 punto *p1; 并且每次将 push_back 内容添加到向量中。

    一件危险的事情要注意,无论您使用 new 关键字创建的内容,之后都没有被删除,这是您的问题中的严重内存泄漏问题。

    如果你真的想玩动态内存,你也可以简单地使用punto p1;Smart Pointers

    【讨论】:

    • @Erick.1993:欢迎。这是另一种更简单的方法,没有人在答案中提到:ideone.com/GAeXpf
    • @Erick.1993:如果您对智能指针感兴趣,这里是您的程序的一种可能方式:ideone.com/37aqaC
    【解决方案2】:

    您可以使用lambda-functions(C++11 起)使您的代码更加简洁:

    sort(list.begin(), list.end(), [x](const punto& lhs, const punto& rhs) {
        if (x == 'x')
            return lhs.x < rhs.x;
        else
            return lhs.y < rhs.y;
    });
    

    [x] 表示变量 x 在 lambda 函数中可见(参见 lambda-capture)。

    【讨论】:

      【解决方案3】:

      您可以使用std::sortstd::vector 进行排序。要对一个类进行排序,它需要定义一个operator&lt;,或者您需要提供一个自定义比较器。

      在您的情况下,变量 xy 也是私有的,为了解决这个问题,我们可以创建可以比较 xy 的友元函数,并将它们作为比较器传递给 std::sort

      #include <iostream>
      #include <vector>
      #include <algorithm>
      using namespace std;
      int n = 0;
      char cr;
      class punto{
      public:
          int x;
          int y;
      public:
          punto();
          ~punto(){}
          void setx(int xn){ x = xn;}
          void sety(int yn) { y = yn; }
          void printcoord();
      
          friend bool compare_x(const punto& lhs, const punto& rhs);
          friend bool compare_y(const punto& lhs, const punto& rhs);
      };
      punto::punto()
      {
          x=0;
          y=0;
      }
      void punto:: printcoord()
      {
          cout << x << " " << y << endl;
      }
      
      bool compare_x(const punto& lhs, const punto& rhs) {
          if (lhs.x == rhs.x)
              return lhs.y < rhs.y;
      
          return lhs.x < rhs.x;
      }
      
      bool compare_y(const punto& lhs, const punto& rhs) {
          if (lhs.y == rhs.y)
              return lhs.x < rhs.x;
      
          return lhs.y < rhs.y;
      }
      int main()
      {
          vector<punto> list;
          int x;
              int y;
              punto *p1;
          cin >> n >> cr;
          for(int contador=0; contador<n; contador++){
              if(contador<n){
                      cin >> x;
                      cin >> y;
                      p1=new punto;
                      p1->setx(x);
                      p1->sety(y);
                      list.push_back(*p1);
                      cin.get();
                  }
              }
          vector<punto>::iterator it;
          if(cr=='x'){
           std::sort(list.begin(), list.end(), compare_x);
           for ( it = list.begin(); it != list.end(); ++it ) {
                  it->printcoord();
           }
          }
          if(cr=='y'){
           std::sort(list.begin(), list.end(), compare_y);
           for ( it = list.begin(); it != list.end(); ++it ) {
                  it->printcoord();
           }
          }
          return 0;
      }
      

      【讨论】:

      • @super 我建议你不要重复OP的糟糕编码,比如p1=new punto;
      【解决方案4】:

      您可以将getters for xy 添加到您的punto 类中,然后您可以将自定义比较器传递给std::sort

      // in class punto
      // add getters to punto
      int getX() {
          return x;
      }
      int getY() {
          return y;
      }
      
      // in main
      std::sort(list.begin(), list.end(), [](punto& a, punto& b) {
          // sort by x
          return a.getX() > b.getX();
          // sort by y
          return a.getY() > b.getY();   
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多