【问题标题】:Checksum for a list of numbers数字列表的校验和
【发布时间】:2016-09-19 22:33:03
【问题描述】:

我有大量的整数列表。我想检查是否有任何列表重复。我在想这样做的一个好方法是计算一个基本的校验和,然后只做一个元素一个元素的检查,如果校验和一致。但是我找不到具有良好属性的校验和算法,即:

  • 有效验证订单;
  • 快速计算;
  • 返回一个小的结果,例如短整数;
  • 分布相当均匀,不同列表重合的概率很低。

例如,为以下 5 次调用返回 [0,65536] 范围内不同数字的函数 check_sum 是理想的。

check_sum([1,2,3,4,5])
check_sum([1,2,3,5,4])
check_sum([5,4,3,2,1])
check_sum([1,2,3,4,4])

我查看了 IPv4 标头校验和算法,它返回的结果大约是正确的大小,但不检查顺序,所以这不是我要找的。​​p>

我打算在python中实现它,但是任何格式都可以用于算法,或者指向一个好的参考资料。

【问题讨论】:

  • hash( tuple([1,2,3,4,5]) ) 不够好吗?
  • 有多少个列表,它们有多大?
  • 列表是搜索算法的结果,所以我试图尽可能地扩展列表的数量,也许是 100k。它们最长可达 100 条,平均为 50 条。
  • 考虑到您相当合理的愿望清单,一个简单的 Adler-32 还不够吗?
  • @felih 那还不算大。你可以做len(lists) > len(set(map(tuple, lists)))。这告诉你是否有任何重复。

标签: python algorithm checksum


【解决方案1】:

如果您想要一些简单的东西,可以使用 Fletcher 校验和的版本。

def check_sum(l):
    sum1 = sum2 = 0
    for v in l:
        sum1 = (sum1 + v) % 255
        sum2 = (sum2 + sum1) % 255
    return sum1*256 + sum2

print(
    check_sum([1,2,3,4,5]),
    check_sum([1,2,3,5,4]),
    check_sum([5,4,3,2,1]),
    check_sum([1,2,3,4,4])
)

【讨论】:

    【解决方案2】:

    hash()计算校验和:

    checksums = \
        list(
            map(
                lambda l:
                    hash(tuple(l)),
                list_of_lists
            )
        )
    

    要知道你有多少重复:

    from collections import Counter
    
    counts = Counter(checksums)
    

    编译一个唯一的列表:

    unique_list = list(dict(zip(checksums, list_of_lists)).values())
    

    【讨论】:

    • 你为什么要写多行 list(map(lambda ... )) 而不是列表理解?
    • @Stefan 你是对的,但对我来说这看起来很清楚,我立即看到了核心和表达式,我们不需要保存在行:)
    【解决方案3】:

    应该是mod 256?

     def check_sum(l):
        sum1 = sum2 = 0
        for v in l:
            sum1 = (sum1 + v) % 256
            sum2 = (sum2 + sum1) % 256
        return sum1*256 + sum2
    
    print(
        check_sum([1,2,3,4,5]),
        check_sum([1,2,3,5,4]),
        check_sum([5,4,3,2,1]),
        check_sum([1,2,3,4,4])
    )
    

    【讨论】:

    • 使用按位使用& 255,这并不要求解释器对% 256很聪明,如果你经常这样做的话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多