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

时间:2018-05-26 23:00:48

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

在下一个代码中我可以输入一个数字 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 y 对坐标进行排序。< / p>

坐标作为对象存储在矢量中。

如果我尝试使用 排序 ,则表示 x y < / em> 是非类型 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

我将不胜感激。

4 个答案:

答案 0 :(得分:2)

  

输出应为:

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

所以基本上你想要按照 y x 对象进行排序。 一种简单的方法是为您的班级operator<

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

为了对wrt x 进行排序,您可以编写一个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关键字创建了什么,之后都没有删除,这是您问题中严重的内存泄漏问题。< / p>

如果您真的想玩动态内存,也可以使用punto p1;或使用Smart Pointers

答案 1 :(得分:1)

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

答案 2 :(得分:0)

您可以使用std::sortstd::vector进行排序。要对类进行排序,需要定义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;
}

答案 3 :(得分:0)

您可以为getters&amp;添加x y到您的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();   
});