我有一大堆名字(数百万)。它们中的每一个都有名字,可选的中间名和姓氏。我需要将这些名称编码为唯一代表名称的数字。编码应该是一对一,即名称应该只与一个数字相关联,而一个数字应该只与一个名称相关联。
对此进行编码的智能方法是什么?我知道根据字母集中的位置(a-> 1,b-> 2 ..等等)标记每个字母表很容易,所以像Deepa这样的名字会得到 - > 455161,但在这里我再说不出“16”是16还是1和6的组合。
所以,我正在寻找一种对名称进行编码的智能方法。
此外,编码应使得任何名称的输出数字中的位数应具有固定的位数,即,它应该与长度无关。这可能吗?
由于 Abhishek S
答案 0 :(得分:9)
要获得相同的宽度数字,你不能只在左边填零吗?
一些选项:
如果您需要能够不时更新您的姓名和号码列表,那么#2,#4和#5应该有效。 #1和#3会有问题。 #5可能是最具前瞻性的,但你可能会发现在某些时候你需要unicode。
我相信你可以使用unicode作为#5的变体,使用2 ^ 32而不是2 ^ 8 == 256的幂。
答案 1 :(得分:2)
你要做的是实际散列(至少如果你有一个固定的数字)。有一些良好的散列算法,碰撞很少。试试sha1,例如,一个经过充分测试并可用于现代语言(参见http://en.wikipedia.org/wiki/Sha1) - 它似乎对git来说已经足够了,所以它可能适合你。
对于两个不同的名称,相同的哈希值当然有一个小的可能性,但是哈希的情况总是如此,并且可以处理。使用sha1等,你不会在名称和ID之间有任何明显的联系,这可能是好事还是坏事,这取决于你的问题。
如果您确实需要独特的ID,则需要执行NealB建议的操作,自己创建ID并在数据库中连接名称和ID(您可以随机创建它们并检查冲突或增加它们,从0000000000001开始左右)。
(在给出一些思考并阅读第一条评论后改进了答案)
答案 2 :(得分:2)
您可以使用BigInteger
对任意字符串进行编码,如下所示:
BigInteger bi = new BigInteger("some string".getBytes());
然后使用字符串:
String str = new String(bi.toByteArray());
答案 3 :(得分:1)
我一直在寻找一个与您提出的问题非常类似的问题的解决方案,这就是我提出的问题:
def hash_string(value):
score = 0
depth = 1
for char in value:
score += (ord(char)) * depth
depth /= 256.
return score
如果你不熟悉Python,那就是它的作用。
ord
值*深度
ord
函数返回每个字符的UTF-8值(0-255)基本上,它的工作方式是初始角色为分数增加更多,而后来的角色贡献越来越少。如果您需要一个整数,请将最终得分乘以2 ** 64。否则,您将具有0-256之间的小数值。此编码方案适用于二进制数据,并且字节/字符中只有256个可能的值。
此方法适用于较小的字符串值,但是,对于较长的字符串,您会注意到十进制值需要比常规double(64位)所能提供的更高的精度。在Java中,您可以使用'BigDecimal',在Python中使用'decimal'模块来增加精度。使用此方法的一个好处是返回的值按排序顺序排列,因此可以“有效”地搜索它们。
答案 4 :(得分:0)
如果每个角色(至少空白)占据一个位置,你可以翻译它。
因此ABC,1,2,3必须翻译成
1*(2*26+1)² + 2*(53) + 3
这样,您可以编码任意字符串,但如果输入的长度不受限制(应该如何?),则不能保证长度的上限。
答案 5 :(得分:0)