C++ 排序坐标存储为向量中的对象

C++ sort coordinates stored as object in vector

在接下来的代码中我可以输入一个数字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

问题是我不知道如何根据 x[=32= 对坐标进行排序]y.

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

如果我尝试使用 sort 它说 x y 是非 class 类型 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

如有任何帮助,我将不胜感激。

Output should be:

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

所以基本上你想对对象 w.r.t 进行排序 yx。 一种简单的方法是为您的 class punto

定义 operator<
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());

为了对 w.r.t xs 进行排序,您可以编写一个 lambda 函数,该函数将使用 getter(您需要在 class punto) 你的 class.

   // 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

您可以使用 std::sortstd::vector 进行排序。要对 class 进行排序,它需要定义 operator< 或者您需要提供自定义比较器。

在你的例子中,变量 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;
}

您可以将 getters for x & y 添加到您的 punto class,然后您可以将自定义比较器传递给 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();   
});

您可以使用 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)。