将随机(条形码值)数字映射到集合中的字符串的好算法是什么?
假设我的应用程序有有限数量的“东西”,在我的例子中,它们将是我的游戏中的项目,但出于这个问题的目的,我将使用字符串。
假设我有 5 个字符串:
- James
- Dave
- John
- Steve
- Jack
将会有一个固定的列表,但是我将来会增加该列表。
问题:我可以使用什么好的算法来从随机数(从条形码生成)转换为上面的这些值之一?
例如,如果我的值是 4523542354254,那么我可以使用什么算法将其映射到 Dave
上?如果我再次拥有相同的号码,我需要确保它每次都映射到 Dave
而不是其他东西。
我确实考虑过的一个选择是采用条形码的最后一位数字并使用 0-9
映射到 10 个项目,但如果我添加第 11 个项目,它就不太适合未来。
有什么建议吗?
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 suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
嗯...如果可以将多个值映射到一个值,您可以使用
Hmm... If it is OK that multiple values can be mapped to the one, you can use
澄清“如果我再次拥有相同的号码,我需要确保它每次都映射到戴夫而不是其他东西。”仅当字符串集不改变时才适用。
最简单的是 Maverik 所说的,
name = names[barcode % name.length];
Java
long
足以存储任何 UPC 条形码,int
不是,所以我假设这里的barcode
是一个long
。请注意,UPC 条形码的最后一位数字是 11 进制,可以是X
。我将其作为读者的练习,如何将条形码实际映射到数字。一种选择是在确定校验码正确后将其丢弃 - 它是根据其他数字计算出来的,因此它不会添加任何信息或区分任何其他相同的代码。但正如 Stephen C 所说,条形码不是随机的,因此这可能不会为您提供跨名称的均匀分布。
为了获得更好的分布,您可以首先对条形码进行哈希处理。例如
name = name[String.valueOf(barcode).hashCode() % names.length];
这仍然可能不完全统一 - 有比
更好但通常更慢的哈希函数String.hashCode
——但它可能避免了现实生活中条形码中可能存在的任何重大偏差。另外,我不记得 Java 模数运算符是否为负输入返回负结果 - 如果是这样,那么您需要将其强制到正范围:
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 herebarcode
is along
. Note that the last digit of a UPC barcode is base-11, it can beX
. 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: