【问题标题】:Python: Iterate through Big Array with BigInts, find first duplicate and printout the indexes of the duplicate ValuesPython:使用 BigInts 遍历大数组,找到第一个重复项并打印出重复值的索引
【发布时间】:2022-01-05 10:19:45
【问题描述】:

对于我大学的密码学课程,我需要比较许多保存在数组中的 SHA 哈希。我需要比较数组索引的值。

数组中有重复项 - 我已经通过一组数组的长度和数组本身的长度之间的比较检查了这一点。

现在我需要有重复值的索引。我找到了很多检查重复项的解决方案,但仅限于短数组。我的数组长度为 300 万,每个索引中的值都在这个长度附近:864205495604807476120572616017955259175325408501。

我编写了一个嵌套循环(来自 Java 并尝试学习 python)。这是我的代码:

counter_outer = 0
while counter_outer < len(hash_value_array):
    counter_inner = counter_outer + 1
    while counter_inner < len(hash_value_array):
        if hash_value_array[counter_outer] == hash_value_array[counter_inner]:
            print(f"*****FOUND MATCH *****")
            print(f"Message [{counter_outer}] Hashvalue has same Value as Message [{counter_inner}]")
            safe_index1 = counter_outer
            safe_index2 = counter_inner
            counter_outer = len(hash_value_array)
            break
        else:
            print("------NO Match-----")
        counter_inner += 1
    counter_outer += 1

你可以想象...这需要很长时间。

对我来说重要的是,我需要重复项所在的索引 - 而不是值。例如,如果索引 100 中有 898,索引 1000001 中有 898,我只需要输出:100, 1000001

有什么建议吗?

【问题讨论】:

  • "有什么建议吗?" - 是的,向我们展示很好的完整示例输入和输出。

标签: python arrays list loops duplicates


【解决方案1】:

您可以在 Python 中按照以下方式进行操作:

假设这个列表有 5 个签名(它们可以是整数或字符串,但我有字符串):

li=['864205495604807476120572616017955259175325408501',
'864205495604807476120572616017955259175325408502',
'864205495604807476120572616017955259175325408503',
'864205495604807476120572616017955259175325408501',
'864205495604807476120572616017955259175325408502']

您可以制作列表的字典,每个列表都是重复项的索引:

idx={}
for i, sig in enumerate(li):
    idx.setdefault(sig, []).append(i)

如果您输入li 3,000,000 个条目,那么在我的计算机上运行大约需要 550 毫秒,并且在您的计算机上可能会类似。

然后您可以像这样找到重复项:

for sig, v in idx.items():
    if len(v)>1:
        print(f'{sig}: {v}')

打印:

864205495604807476120572616017955259175325408501: [0, 3]
864205495604807476120572616017955259175325408502: [1, 4]

如果你只想要第一个副本,你可以像这样修改第一个循环:

idx={}
for i, sig in enumerate(li):
    if sig in idx:
        print(f'Duplicate {sig} at {idx[sig]} and {i}')
        break 
    else:
        idx[sig]=i

打印:

Duplicate 864205495604807476120572616017955259175325408501 at 0 and 3

但老实说 - 我不明白为什么这要快得多。

你的速度非常慢,因为它具有来自嵌套 while 循环的 O n**2 复杂性。您正在为每个元素循环整个数组。我在这里向您展示的方法仅在整个列表中循环一次——而不是 300 万次!

【讨论】:

  • 但是它在哪里检查它是否在代码中重复?
  • @fancyStuff90:我补充说。谢谢。
  • 哇,谢谢!这太神奇了——我的代码在大约 2 小时后@迭代数组索引 200/3000000。你的在几秒钟内就做到了——很棒的人。我投票给你的答案,但它显示的似乎我“低”了:(但再次 - 谢谢!但老实说 - 我不明白为什么这要快得多。
  • @fancyStuff90:我通过编辑回答了您的问题。正是嵌套的 while 循环让你的循环如此缓慢。阅读 Big O 以了解计算复杂性。
猜你喜欢
  • 1970-01-01
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 2017-07-12
相关资源
最近更新 更多