What is a good algorithm for mapping random (barcode values) numbers to an String in a collection?
Say that my application has a finite number of "stuff", in my case they will be items in my game but for the purposes of this question I'll use Strings.
Say I have 5 Strings :
- James
- Dave
- John
- Steve
- Jack
There will be a set list of them, however I will increase that list in the future.
Question : What is a good algorithm I can use, to go from a random number (generated from a barcode) into one of those values from above?
For example, if I have the value 4523542354254, then what algorithm could I use to map that onto Dave
? If I have that same number again, I need to make sure it maps to Dave
and not to something else each time.
One option I did consider was taking the last digit of the barcode and using the 0-9
that would map onto 10 items, but its not very future proof if I added an 11th item.
Any 开发者_Go百科suggestions?
Hmm... If it is OK that multiple values can be mapped to the one, you can use
string name = names[value % number_of_names];
With the clarification that "If I have that same number again, I need to make sure it maps to Dave and not to something else each time." only applies as long as the set of strings doesn't change.
Simplest is what Maverik says, name = names[barcode % names.length];
A Java long
is big enough to store any UPC barcode, int
isn't, so I assume here barcode
is a long
. Note that the last digit of a UPC barcode is base-11, it can be X
. I leave it as an exercise for the reader how you actually map barcodes to numbers. One option is just discard the check digit once you've established that it's correct - it's computed from the others, so it doesn't add any information or discriminate between any otherwise-equal codes.
But as Stephen C says, barcodes aren't random, so this might not give you a uniform distribution across the names.
To get a better distribution, you could first hash the barcode. For example name = names[String.valueOf(barcode).hashCode() % names.length];
This still might not be entirely uniform -- there are better but usually slower hash functions than String.hashCode
-- but it probably avoids any major biases that there may be in real-life barcodes.
Also, I can't remember whether the Java modulus operator returns negative results for negative input - if so then you need to coerce it into a positive range:
int idx = String.valueOf(barcode).hashCode() % names.length;
if (idx < 0) idx += names.length;
精彩评论