0

I want to make structure storing value with two keys - 'x' and 'y'. I thought i will use std::map>. But I think it would be better to use just one std::map and combine both keys into one key (I will call it 'p').

So I need function p->(x,y) and function (x,y)->p. Both 'x' and 'y' are integer types with negative values allowed.

I think that it should be possible but I am surprised that I did not find tons of articles about it on the internet.

I have some ideas about how to do it, but all seems too complicated. Could you please give me some advices about how to do it or what topics to read about this problematics?

Example of possible mapping (but I need mathematical form of something like that): https://i.stack.imgur.com/UbVaM.png

Thank you for any advices :-)

Ivorne
  • 191
  • 6
  • What is the range of `(x, y)` ? – Jarod42 Sep 09 '14 at 19:56
  • X and Y are just some signed integer types. For example 'int'. – Ivorne Sep 09 '14 at 19:59
  • Why not use some grid (as if all values were positive with correct offset) ? – Jarod42 Sep 09 '14 at 20:59
  • Hmm, right. I was thinking about infinite number of values. But in fact, when there is only limited number of values, I can use: p=sqrt(max_value(key_type))*x+y ; x=p%max_value(key_type)) ; y=floor(p/max_value(key_type))) – Ivorne Sep 09 '14 at 21:26
  • If all you really want is a hash function for pair of numbers then Joshua Bloch's hashcode function for Java has a good pedigree http://stackoverflow.com/questions/18473071/how-caching-hashcode-works-in-java-as-suggested-by-joshua-bloch-in-effective-jav It has the advantage of being fast which is what you want for hash function but it is one way only. – Salix alba Sep 10 '14 at 06:16

3 Answers3

1

I would just use a std::map<std::tuple<int,int>, int> for example, where your tuple is (x,y) and the value is z. Otherwise it will be difficult to keep a 1-to-1 mapping of p(x,y) to z.

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • This looks easier than my approach. But this does not work with std::unordered_map. Any ideas how to make it work with unordered_map? I could make hash function for std::tuple but I am afraid that I am not skilled enough to be sure that I will not cause any performance problems. Sure, I could still use std::map. – Ivorne Sep 09 '14 at 19:50
0

How about using union?

union p_t {
    p_t(int64_t c) : k(c) {}
    p_t(int32_t a, int32_t b) : x(a), y(b) {}
    int64_t k;
    struct { int32_t x, y; };
};

std::map<decltype(p_t::k), int> m1;
std::unordered_map<decltype(p_t::k), int> m2;
p_t p = p_t(rand(), rand());
m1[p.k] = rand();
m2[p.k] = rand();

Live example: http://ideone.com/jebyG6

Aleksandr Belkin
  • 412
  • 5
  • 17
0

You could try and use functions similar to that used to show there are as many fractions as whole numbers This gives a unique integer for each fraction and a unique fraction for each positive integer. It works just as well for x, y coordinates. The two functions p->(x,y) and (x,y)->p are a little complicated but possible to write. You could adapt the idea using some sort of spiral shape.

assigning integers to fractions form wikipedia Rational_number.

Image from https://commons.wikimedia.org/wiki/File:Diagonal_argument.svg

Salix alba
  • 7,536
  • 2
  • 32
  • 38
  • I tried that. This is possible and not so hard. Surprisingly, when i try to generalise it for both positive and negative values, it is becoming quite complicated. – Ivorne Sep 09 '14 at 23:19
  • Yes its maybe not easiest path to find a formula for. There are several easy ways to go from positive whole numbers to the full set of integers. You could map odd numbers to negatives and even numbers for positive so 0 -> 0, 1 -> -1, 2 -> 1, 3 -> -2, 4 -> 2. Combine that with the above and you can get a map from the integers to pairs of integers. – Salix alba Sep 10 '14 at 06:06