将名称字符串编码为唯一编号

时间:2012-04-26 17:43:15

标签: string algorithm math text

我有一大堆名字(数百万)。它们中的每一个都有名字,可选的中间名和姓氏。我需要将这些名称编码为唯一代表名称的数字。编码应该是一对一,即名称应该只与一个数字相关联,而一个数字应该只与一个名称相关联。

对此进行编码的智能方法是什么?我知道根据字母集中的位置(a-> 1,b-> 2 ..等等)标记每个字母表很容易,所以像Deepa这样的名字会得到 - > 455161,但在这里我再说不出“16”是16还是1和6的组合。

所以,我正在寻找一种对名称进行编码的智能方法。

此外,编码应使得任何名称的输出数字中的位数应具有固定的位数,即,它应该与长度无关。这可能吗?

由于 Abhishek S

6 个答案:

答案 0 :(得分:9)

要获得相同的宽度数字,你不能只在左边填零吗?

一些选项:

  1. 对它们进行排序。数数吧。第10个名字是10号。
  2. 将每个字符视为基数26中的数字(不区分大小写,不 数字)或52(大小写,无数字)或36(不区分大小写 带数字)或62(用数字区分大小写)编号。计算 int中的值。 EG,名称为“abc”,你有0 * 26 ^ 2 + 1 * 26 ^ 1 + 2 * 20 ^ 0。有时中文名称可能会使用数字来表示音调。
  3. 使用“完美哈希”方案:http://en.wikipedia.org/wiki/Perfect_hash_function
  4. 这个主要是有趣的建议:使用goedel编号:)。所以 “abc”将是2 ^ 0 * 3 ^ 1 * 5 ^ 2 - 它是素数幂的乘积。 保理号码可以让你回到角色。数字 虽然可能会变得很大。
  5. 如果您尚未使用它,请转换为ASCII。然后对待每一个 字符的序数作为base-256编号系统中的数字。 所以“abc”是0 * 256 ^ 2 + 1 * 256 ^ 1 + 2 * 256 ^ 0。
  6. 如果您需要能够不时更新您的姓名和号码列表,那么#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,那就是它的作用。

  1. 得分最初为0,深度设为1
  2. 为每个角色添加ord值*深度
    1. ord函数返回每个字符的UTF-8值(0-255)
    2. 然后它乘以'深度'。
  3. 最后深度除以256。
  4. 基本上,它的工作方式是初始角色为分数增加更多,而后来的角色贡献越来越少。如果您需要一个整数,请将最终得分乘以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)

看看http://en.wikipedia.org/wiki/Huffman_coding。这是标准方法。