【问题标题】:I need a function that given similar inputs returns similar indexes我需要一个给定相似输入的函数返回相似索引
【发布时间】:2011-10-11 23:30:02
【问题描述】:

所以我查看了哈希函数,发现给定 2 个相似的字符串,即使相差一位,结果也会是完全不同的哈希键。我实际上需要创建某种唯一的 id,它具有与相似输入非常相似的特性(将是数百万个字母数字字符串)。

例子:

  • 两个相等的字符串必须具有相同的哈希值。
  • 两个不同的字符串必须有不同的哈希值。
  • 两个非常相似的不同字符串必须具有不同的哈希值,同时彼此之间的距离不会太远。

什么是实现这一目标的好方法?我正在使用 python。

【问题讨论】:

  • "两个不同的字符串必须有不同的哈希值。"这是不可能的,除非哈希比可能的最长字符串长。 “两个非常相似的不同字符串必须具有不同的哈希值,同时彼此之间的距离不会太远。”如果您不需要加密安全,您可以使用一些简化的散列函数版本。
  • 使用原始字符串并存储某种形式的列文斯坦距离?
  • 你能解释一下你想用这个做什么吗?可能有更好的方法来实现您的最终结果。
  • 我不需要加密安全。当我说它们必须不同时,我的意思是尽可能不发生冲突。
  • 我需要比较非同质数据(数字和字符串组合),可能会出现输入错误等错误

标签: python hash indexing


【解决方案1】:

您所要求的是不可能的,假设“相似哈希”是指这些值应该具有相似的大小 - 例如,12345 与 12346 相似,但与 92345 不相似。原因是这种排序是一维的(数轴),但字符串彼此相似的方式没有固定的维度(例如,'foo'、'fob' 和 'fod' 彼此之间的距离均为 1)。

如果您想执行模糊匹配,则需要使用不同的方法来索引您的文本,例如 thisthis

如果您只想比较单个值的相似度,请不要一开始就对它们进行哈希处理 - 只需立即计算它们的编辑距离。

【讨论】:

    【解决方案2】:

    如果您确定始终拥有字母数字数据,我建议您使用 base 36(或更高)算法。

    你可以使用我给出的方法作为这个问题的答案:Base 62 conversion

    import string
    BASE_LIST = string.digits + string.letters
    BASE_DICT = dict((c, i) for i, c in enumerate(BASE_LIST))
    
    def base_decode(string, reverse_base=BASE_DICT):
        length = len(reverse_base)
        ret = 0
        for i, c in enumerate(string[::-1]):
            ret += (length ** i) * reverse_base[c]
    
        return ret
    
    def base_encode(integer, base=BASE_LIST):
        length = len(base)
        ret = ''
        while integer != 0:
            ret = base[integer % length] + ret
            integer /= length
    
        return ret
    

    示例用法:

    for i in range(100):                                    
        print i, base_decode(base_encode(i)), base_encode(i)
    

    【讨论】:

      【解决方案3】:

      我相信以下内容满足您的要求。

      def gethash(data):
        u"given a character string return an integer hash value"
        return reduce(lambda b1, b2: (b1 << 8) + b2,
            imap(ord, unicodedata.normalize('NFC', data).encode('UTF-8')))
      

      本质上,哈希值是输入的 UTF-8 编码字节值的完整二进制值,作为单个整数。相似的字符串产生具有相似位的哈希值(并不总是具有小的减法差异,但您没有指定)。规范化导致字符串u'A\u030a'u'\xc5' 具有相同的哈希值。

      如果你想限制最大值,那么最后一步只需应用模除法(可能是 2^32)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-07
        • 2019-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多