Координаты сортировки C ++ хранятся как объекты в векторе - PullRequest
0 голосов
/ 27 мая 2018

В следующем коде я могу ввести число 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 .

Координаты сохраняются как объекты внутри вектора.

Если я пытаюсь использовать sort , это говорит о том, что x и y не относятся к классу 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 голосов
/ 27 мая 2018

Вы можете использовать лямбда-функции (начиная с 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 видимавнутри лямбда-функции (см. лямбда-захват ).

0 голосов
/ 27 мая 2018

Вы можете использовать std :: sort для сортировки std::vector.Чтобы отсортировать класс, ему нужно задать operator< или указать собственный компаратор.

В вашем случае переменные x и y также являются частными, чтобы обойти это, мы можемсоздать дружественные функции, которые могут сравнивать x и y и передавать их в качестве компараторов в 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;
}
0 голосов
/ 27 мая 2018

Вы можете добавить getters для 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();   
});
0 голосов
/ 27 мая 2018

Выходные данные должны быть:

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

Чтобы отсортировать по x с, вы можете написать lambda функцию, которая будет использовать геттеры (которые вам нужно определить в классе 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(); });

СМОТРИТЕ ВЫХОД ЗДЕСЬ


Однако я не понял, почему вы создалиpunto *p1; и каждый раз, когда у вас есть push_back содержимое для вектора.

Еще одна опасная вещь - заметить, что все, что вы создали с помощью ключевого слова new, не было удалено после, что является серьезной утечкой памяти в вашей проблеме.

Вы также можете просто использовать punto p1; или Умные указатели , если вы действительно хотите играть с динамической памятью.

...