Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 将名称字符串编码为唯一的数字_String_Algorithm_Math_Text - Fatal编程技术网

String 将名称字符串编码为唯一的数字

String 将名称字符串编码为唯一的数字,string,algorithm,math,text,String,Algorithm,Math,Text,我有一大套名字(数以百万计)。它们每个都有一个名字、一个可选的中间名和一个姓氏。我需要将这些名称编码成一个唯一表示名称的数字。编码应为一个一,即名称应仅与一个数字关联,而数字应仅与一个名称关联 什么是一种聪明的编码方式?我知道根据名称在字母表集中的位置(a->1,b->2..等等)标记名称的每个字母表很容易,因此像Deepa这样的名称会得到->455161,但这里我无法确定“16”是真的16还是1和6的组合 因此,我正在寻找一种智能的名称编码方法 此外,编码应使得任何名称的输出数字中的位数应具有

我有一大套名字(数以百万计)。它们每个都有一个名字、一个可选的中间名和一个姓氏。我需要将这些名称编码成一个唯一表示名称的数字。编码应为一个一,即名称应仅与一个数字关联,而数字应仅与一个名称关联

什么是一种聪明的编码方式?我知道根据名称在字母表集中的位置(a->1,b->2..等等)标记名称的每个字母表很容易,因此像Deepa这样的名称会得到->455161,但这里我无法确定“16”是真的16还是1和6的组合

因此,我正在寻找一种智能的名称编码方法

此外,编码应使得任何名称的输出数字中的位数应具有固定的位数,即,其应独立于长度。这可能吗

谢谢
Abhishek S

您在那里试图做的实际上是散列(至少如果您有固定数量的数字)。有一些很好的哈希算法,冲突很少。试一试sha1,例如,它经过了很好的测试,可用于现代语言(请参阅)——它对于git来说似乎已经足够好了,所以它可能适合您

当然,对于两个不同的名称使用相同的哈希值的可能性很小,但哈希始终是这样,可以处理。使用sha1之类的工具,名称和ID之间不会有任何明显的联系,这可能是好事,也可能是坏事,这取决于您的问题

如果您确实想要唯一的ID,那么您需要像NealB建议的那样,自己创建ID,并在数据库中连接名称和ID(您可以随机创建它们,检查冲突或增加它们,从0000000000001左右开始)


(仔细思考并阅读第一条评论后,答案会有所改进)

如果每个字符(至少加上空格)都占据一个位置,你可以翻译它

因此,ABC,即1,2,3必须翻译成

1*(2*26+1)² + 2*(53) + 3

通过这种方式,您可以对任意字符串进行编码,但如果输入的长度没有限制(应该如何限制?),则无法保证长度有上限

看一看。这是标准的方法。

要获得相同的宽度编号,您不能只将左侧的焊盘归零吗

一些选择:

  • 把它们分类。数一数。第十个名字是数字10
  • 将每个字符视为基数为26的数字(不区分大小写,不区分大小写) 数字)或52(不区分大小写,无数字)或36(不区分大小写) 带数字)或62(区分大小写带数字)号码。计算 整数中的值。例如,对于“abc”名称,您将有0*26^2+1* 26^1 + 2 * 20^0. 有时中国人的名字可能会用数字来表示音调
  • 使用“完美哈希”方案:
  • 这一条主要是在娱乐中建议的:使用goedel编号:)。所以 “abc”应该是2^0*3^1*5^2——它是素数幂的乘积。 分解数字会返回字符。数字 可能会变得很大
  • 如果尚未使用,请转换为ASCII。然后分别治疗 在基数为256的编号系统中,作为数字的字符序号。 所以“abc”是0*256^2+1*256^1+2*256^0
  • 如果您需要能够随时更新姓名和号码列表,那么#2、#4和#5应该可以使用#1和#3会有问题#5可能是最经得起未来考验的,尽管您可能会发现在某些时候需要unicode


    我相信您可以将unicode作为#5的一个变体,使用2^32的幂,而不是2^8==256。

    我一直在寻找一个与您提出的问题非常相似的解决方案,这就是我想到的:

    def hash_string(value):
        score = 0
        depth = 1
        for char in value:
            score += (ord(char)) * depth
            depth /= 256.
        return score
    
    如果您不熟悉Python,下面是它的功能

  • 分数最初为0,深度设置为1
  • 对于每个字符,添加
    ord
    值*深度
  • ord
    函数返回每个字符的UTF-8值(0-255)
  • 然后乘以“深度”
  • 最后,深度除以256
  • 从本质上讲,它的工作方式是,最初的角色增加更多的分数,而后来的角色贡献越来越少。如果需要整数,则将最终分数乘以2**64。否则,十进制值将在0-256之间。这种编码方案适用于二进制数据,因为一个字节/字符中只有256个可能的值


    此方法适用于较小的字符串值,但是,对于较长的字符串,您会注意到十进制值需要比常规双精度(64位)更高的精度。在Java中,可以使用“BigDecimal”,在Python中,可以使用“decimal”模块来提高精度。使用此方法的一个好处是,返回的值按排序顺序排列,因此可以“高效”搜索它们。

    您可以使用
    biginger
    对任意字符串进行如下编码:

    BigInteger bi = new BigInteger("some string".getBytes());
    
    要恢复字符串,请使用:

    String str = new String(bi.toByteArray());
    

    如果您想将答案限制在固定位数,这是最好的方法。否则,将它们实现为以26为基数的整数。不,他要求的是1:1的映射,这不是散列。但在我看来,从名称中计算一个值并要求一个固定长度的值会导致散列(至少在名称长度不受限制的情况下)@NickJohnson散列理论上不是一对一。但在现实生活中,你遇到一条的几率比宇宙线在错误时刻翻转的几率低几个数量级。如果你不担心第二个,为什么要担心第一个呢?@B我并不是说加密哈希在这里不起作用(尽管很难说OP真正想要实现什么)-只是你的第一句话“你在那里试图做的实际上是哈希”。这不能解决固定长度问题