1

I have a class for holding my Points in 2D space like this:

class Point{
public:
Point(double a, double b){ x = a; y = b; }

//some additional information

private:
    double x, y;
};

I like to have these Points in a std::set but I dont know how to write the compare struct

struct cCompare{
    bool operator()(const Point &p1, const Point &p2){
         //what should I write here??
    }
};

Two Points like p and q are equal if (p_1,p_2) = (q_1,q_2). Do I have to store some additional information in my Point class? Something like index or any unique number for each Point? And have something like this:

struct cCompare{
    bool operator()(const Point &p1, const Point &p2){
         return (p1.index < p2.index);
    }
};
MoNo
  • 307
  • 4
  • 15
  • Why not providing `bool Point::operator<(const Point& other)` in 1st place? – πάντα ῥεῖ Dec 28 '14 at 12:20
  • 2
    You may use: `return std::tie(p1.x, p1.y) < std::tie(p2.x, p2.y);` – Jarod42 Dec 28 '14 at 12:20
  • @πάνταῥεῖ Why shouldn't I use this way?(the struct way) – MoNo Dec 28 '14 at 12:22
  • 1
    @MoNo 1. It's idiomatic 2. `p1 < p2` is more natural, no? – legends2k Dec 28 '14 at 12:23
  • @MoNo Well, the point of classes is to encapsulate the data and operations applied to them, isn't it? – πάντα ῥεῖ Dec 28 '14 at 12:24
  • 1
    As the order relationship between Point is not natural/intuitive, I would say that having the order outside of Point is not bad. – Jarod42 Dec 28 '14 at 12:27
  • Why would you want to store data that cannot be naturally sorted in a sorted container in first place? Won't `std::vector` do the trick? – Ivan Aksamentov - Drop Dec 28 '14 at 12:36
  • @Drop Im trying to implement an algorithm, and in that algorithm its said that I should use a red black tree for holding my data in order to find and delete elements faster, so I used std::set. – MoNo Dec 28 '14 at 12:39
  • @MoNo: if the order has no meaning to the algorithm, and all you need is a collection that can insert, remove and find particular values, then you'd probably be better off with `unordered_set`, and implement a hash instead of a comparator. Perhaps the advice was written before that was added to the standard. – Steve Jessop Dec 28 '14 at 12:42
  • @SteveJessop Thanks for your advice, My algorithm says that I should be able to find any elements in O(lgn), A red-black tree can do this for me, Why do you suggest that I should use `unordered_set`? is it faster? – MoNo Dec 28 '14 at 12:48
  • @Jarod42 Yes you are right, I also need to sort my `Points` based on their distance from some other points. so I need to write maybe more than 3 or 4 compare structs. – MoNo Dec 28 '14 at 12:52
  • I would recommend a spatial index for this. It will have superior performance. – user2672165 Dec 28 '14 at 12:59
  • @MoNo: with certain caveats, `unordered_set` has constant-time lookup and amortised constant-time insert, and typically both are faster than a R-B tree. The caveats are that there exist bad worst cases where all your data collides on the same hash value, and everything becomes linear. So the data structure to use might depend whether you're after best worst-case complexity or best practical performance. – Steve Jessop Dec 28 '14 at 12:59

1 Answers1

6

If you need just any ordering relation for the sake of storing in a set, you could use the dictionary order:

P1 < P2 iff P1.x < P2.x || (P1.x == P2.x && P1.y < P2.y)

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458