OK, so the task is this, I would be given (x, y) co-ordinates of points with both (x, y) ranging from -10^6 to 10^6 inclusive. I have to check whether a particular point e.g. (x, y) tuple was given to me or not. In simple words how do i answer the query whether a particular point(2D) is set or not. So far the best i could think of is maintaining a std::map<std::pair<int,int>, bool>
and whenever a point is given I mark it 1. Although this must be running in logarithmic time and is fairly optimized way to answer the query I am wondering if there's a better way to do this.
Also I would be glad if anyone could tell what actually complexity would be if I am using the above data structure as a hash.I mean is it that the complexity of std::map
is going to be O(log N) in the size of elements present irrespective of the structure of key?
Instead of mapping each point to a bool, why not store all the points given to you in a set? Then, you can simply search the set to see if it contains the point you are looking for. It is essentially the same as what you are doing without having to do an additional lookup of the associated bool. For example:
Then, you can check whether the set contains a certain point or not like this :
As mentioned,
std::set
is normally implemented as a balanced binary search tree, so each lookup would take O(logn) time.If you wanted to use a hash table instead, you could do the same thing using
std::unordered_set
instead ofstd::set
. Assuming you use a good hash function, this would speed your lookups up to O(1) time. However, in order to do this, you will have to define the hash function forpair<int, int>
. Here is an example taken from this answer:Edit: Nevermind, I see you already got it working!
In order to use a hash map you need to be using
std::unordered_map
instead ofstd::map
. The constraint of using this is that your value type needs to have a hash function defined for it as described in this answer. Either that or just use boost::hash for this:std::unordered_map<std::pair<int, int>, boost::hash<std::pair<int, int> > map_of_pairs;
Another method which springs to mind is to store the 32 bit int values in a 64 bit integer like so:
As described in this answer. The x and y components can be stored in the high and low bytes of the integer and then you can use a
std::unordered_map<uint64_t, bool>
. Although I'd be interested to know if this is any more efficient than the previous method or if it even produces different code.