3

I have those classes and I want to sort an array of objects, considering x coordinate, and sort just those with a particular value to an attribute.

Class.h
#include <iostream>
#include <algorithm>

class Punct2D
{
protected:
    int x, y;
public:
    Punct2D() {};
    ~Punct2D() {};

    int get_x() const;
    int get_y() const;
    void set_x(const int x);
    void set_y(const int y);
    friend std::ostream &operator << (std::ostream &flux, Punct2D dot);
    friend std::istream &operator >> (std::istream &flux, Punct2D &dot);
};

class Punct2DColorat :public Punct2D
{
private:
    char *color;
public:
    Punct2DColorat() { this->color = NULL; };
    ~Punct2DColorat() {};

    char *get_color();
    void set_color(char *color);
    bool operator<(Punct2DColorat dot);

}; 

Here I have the implementation.

#include "Class.h"

int Punct2D::get_x() const
{
    return this->x;
}
int Punct2D::get_y() const
{
    return this->y;
}
void Punct2D::set_x(const int x)
{
    this->x = x;
}
void Punct2D::set_y(const int y)
{
    this->y = y;
}

char *Punct2DColorat::get_color()
{
    return this->color;
}
void Punct2DColorat::set_color(char *color)
{
    this->color = new char[strlen(color) + 1];
    for (int i = 0; i < strlen(color) + 1; i++) this->color[i] = color[i];
}
bool Punct2DColorat::operator<(Punct2DColorat dot)
{
    return this->x < dot.get_x();
}

std::ostream &operator << (std::ostream &flux, Punct2D dot)
{
    flux << "Punct(" << dot.get_x() << "," << dot.get_y() << ")\n";
    return flux;
}
std::istream &operator >> (std::istream &flux, Punct2D &dot)
{
    std::cout << "Introduceti x :";
    flux >> dot.x;
    std::cout << "Introduceti y :";
    flux >> dot.y;
    return flux;
}

And here is the Main.

#include "Class.h"

void main()
{
    int n, it = 0; char *aux = new char[15]; bool value;
    Punct2DColorat *dots;

    std::cout << "Cate puncte introduceti :"; std::cin >> n;
    dots = new Punct2DColorat[n];

    for (int i = 0; i < n; i++)
    {
        std::cout << "Introduceti 0 pentru Punct2D, respectiv 1 pentru Punct2D colorat :";
        std::cin >> value;
        if (value)
        {
            std::cin >> dots[i];
            std::cout << "Introduceti culoarea punctului :";
            std::cin >> aux;
            dots[i].set_color(aux);
        }
        else
        {
            std::cin >> dots[i];
        }
    }

    std::sort(dots, dots + n, [](Punct2DColorat dot) { return dot.get_color() != NULL; });

    for (int i = 0; i < n; i++)
    {
        std::cout << dots[i];
        if (dots[i].get_color() != NULL)
        {
            std::cout << "Culoare :" << dots[i].get_color() << "\n";
        }
        std::cout << "\n";
    }
} 

I want to sort the dots with color !=NULL, I tried this, it works but I have a runtime error.

bool Punct2DColorat::operator<(Punct2DColorat dot)
{
    if ((this->color != NULL) && (dot.get_color() != NULL))return this->x < dot.get_x();
    return true;
} 

How can I sort just the objects with color !=NULL and the other objects with color==NULL remain in the same position?

Here is an example:

//If have 3 objects in the following order stored in the dots array.
dots[0].get_x()=3;
dots[0].get_y()=3;
dots[0].get_color()="Red";

dots[1].get_x()=0;
dots[1].get_y()=0;
dots[1].get_color()=NULL;

dots[2].get_x()=1;
dots[2].get_y()=1;
dots[2].get_color()="Blue";

//After sort i want to have them like this:
dots[0].get_x()=1;
dots[0].get_y()=1;
dots[0].get_color()="Blue";

dots[1].get_x()=0;
dots[1].get_y()=0;
dots[1].get_color()=NULL;

dots[2].get_x()=3;
dots[2].get_y()=3;
dots[2].get_color()="Red";

Thanks.

8
  • void main is wrong. main must return int. Commented May 20, 2017 at 9:58
  • How should your example look after been sorted? Commented May 20, 2017 at 10:01
  • I just changed the type returned by main and it did not change anything at all. Commented May 20, 2017 at 10:01
  • @manni66 I have a comment where you can see the example after sort.Is it in the example block. Commented May 20, 2017 at 10:02
  • The null color being sorted to front/back is easy. Leaving them in place is hard, you would need a filter iterator. A random access filter iterator is hard. Reexamine your requirements? Commented May 20, 2017 at 10:06

1 Answer 1

4

The problem is, your comparison operator evaluates to true for any couple of non-colored points. A possible solution is to construct a second vector, sort it and re-insert

std::vector<Punct2DColorat> tmp;
for (int i = 0; i < n; i++)
{
    if (dots[i].get_color() != NULL)
    {
        tmp.push_back(dots[i]);
    }
}
std::sort(tmp.begin(), tmp.end());
int j = 0;
for (int i = 0; i < n; i++)
{
    if (dots[i].get_color() != NULL)
    {
        dots[i] = tmp[j];
        ++j;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I did not think at this, your solution it's amazing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.