0

Say I have a list of unique numbers (e.g. 105, 342, 432, 34, etc.) and I want to map them to indices (0,1,2,3, etc.). Is there a general way to do this? If not, assume that you know beforehand all the numbers in the list and you can hard code their values. And if that doesn't help, another limiting factor could be that the numbers are "nearly consecutive." This means they are consecutive for the most part but there may exist gaps (which you know about ahead of time).

ballaw
  • 1,489
  • 6
  • 20
  • 28

1 Answers1

1

What you want to do is essentially to implement a hash map (or a dictionary). There are many libraries for a lot of languages that implement this kind of structure.
What happens under the hood, in a very simplified way, is, say, an array and a hashing function that maps your numbers to one of the indices of the array, in a way to achieve O(1) amortized access to your elements based on their key.
A second important aspect is how you deal with collisions. Say for example that your hashing function for your numbers is f(x) = x mod 10. Both 13 and 33 would be hashed to 3. This is a collision and it must be dealt with. You could for example, create ordered lists of elements and assigning these to your array's slots. When searching for element, you would hash its key and search the list in the designated array's position for an exact key match.
This is only the beginning of it all, and you may find more information about all this in Hash function and Hash map on wikipedia.
It is worth mentioning that in your case you only want to store the keys themselves. Usually we need to store more complex objects and search for them by their keys, which typically are numbers or strings, but could also be any kind of more complex object.

EDIT
I just realized that your question is much more about finding the best hash function for your specific scenario than the more general solution to problems similar to yours.
If I understand right, you are saying that you know the numbers beforehand? If this really is the case, you can just if the numbers assigning each one of them one of the indices in your array, in a very hard-coded form (as you suggested yourself), such as:

if (num == 105)
    idx = 0;
else if (num == 342)
    idx = 1;
...

In case you do not know your numbers, but you know, say, the smallest and the greatest of them, you can hash them to indices with:

f(x) = (x - smallest_num) mod (greatest_num - smallest_num + 1)  

In this case, f(x) is a perfect hashing function, which means there won't be any collisions. Your array will still have some of its slots empty, given that your numbers are not always consecutive.

Note: I am still not sure what you intend to do with this, and thus I'm not sure I answered your question correctly. Specially the fact that you may know your numbers beforehand, or that you may know a lot about them, confuses me. Maybe if your purpose were clarified, we could give you ways to achieve your goal differently.

Community
  • 1
  • 1
Marcelo Zabani
  • 2,139
  • 19
  • 27