2

给定一个输入字符串,字符串长度不会超过 30,输出将是一个唯一的 id 号。Java中有没有办法可以做到这一点?相同的字符串总是会生成相同的id,不同的字符串不能生成相同的id。java HashCode() 可以做到这一点吗?

谢谢

4

5 回答 5

3

为了满足要求

相同的字符串总是会生成相同的id,不同的字符串不能生成相同的id

你会得到相当大的数字。您要求该函数是单的,因此您需要与可能的 s 数量一样多的数字,String在您的情况下类似于 $255^30$(或者如果您允许任意 Unicode 字符,则类似于 $65536^30$)。因此,您将需要BigIntegers 并且肯定会使用int(只是String长度不超过 30 的 s 比 中的数字多int)。例如,new BigInteger(theString.getBytes(""))满足您的要求。

如果你使用hashCode,你会失去单射性,但是在大多数情况下,两个Strings 相同的机会hashCode非常低(实际上散列的目的是为了降低这个机会)。如果您想更加确定冲突的数量一致地很小,您可以使用一些加密哈希函数,但是映射不会是单射的。

也许解释您的要求的原因将有助于找到最佳解决方案。

于 2012-08-24T13:00:05.837 回答
1

Java 哈希码不保证是唯一的。您需要查看 UUID。

public static UUID nameUUIDFromBytes(byte[] name)

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/UUID.html

于 2012-08-24T12:45:47.833 回答
0

也许这有点傻,但是将每个字符转换为 ASCII 数字怎么样?

于 2012-08-24T12:45:57.353 回答
0

如果你真的需要确保没有冲突,那么你得到的数字将是巨大的,肯定比任何原始数字类型都要大。我的建议是使用几乎可以肯定足够好的 SHA-1 哈希(Git 版本控制系统依赖于这些哈希值的唯一性,您的要求真的比他们的要求更严格吗?)

如果你想保证唯一性,那么我想你可以这样做的一种方法是为每个字符获取 ASCII(或 Unicode,取决于你的输入)数值,用零填充它,以便所有值都具有相同的长度,并且然后将它们连接在一起成为一个大数字。如前所述,您无法将其放入 long 值中,因此您需要使用 BigInteger 类。填充是必要的,以避免像“12 + 34”和“123 + 4”这样的冲突。

于 2012-08-24T12:47:03.960 回答
0

除非您可以确定性地限制有效字符串集,否则您唯一的选择是将整个字符串解释为您的 id。当您要获得非常大的 id 时,您应该使用 BigInteger 类来表示它们。

我会以相反的顺序转换字符,以免担心不同长度的字符串。

于 2012-08-24T12:51:55.480 回答