将随机(条形码值)数字映射到集合中的字符串的好算法是什么?

发布于 2024-10-31 18:30:51 字数 500 浏览 1 评论 0原文

假设我的应用程序有有限数量的“东西”,在我的例子中,它们将是我的游戏中的项目,但出于这个问题的目的,我将使用字符串。

假设我有 5 个字符串:

  1. James
  2. Dave
  3. John
  4. Steve
  5. 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 :

  1. James
  2. Dave
  3. John
  4. Steve
  5. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Hello爱情风 2024-11-07 18:30:51

嗯...如果可以将多个值映射到一个值,您可以使用

string name = names[value % number_of_names];

Hmm... If it is OK that multiple values can be mapped to the one, you can use

string name = names[value % number_of_names];
不必了 2024-11-07 18:30:51

澄清“如果我再次拥有相同的号码,我需要确保它每次都映射到戴夫而不是其他东西。”仅当字符串集不改变时才适用。

最简单的是 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 模数运算符是否为负输入返回负结果 - 如果是这样,那么您需要将其强制到正范围:

int idx = String.valueOf(barcode).hashCode() % names.length;
if (idx < 0) idx += names.length;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文