Python:用BigInts遍历Big Array,找到第一个重复项并打印出重复值的索引
Python: Iterate through Big Array with BigInts, find first duplicate and printout the indexes of the duplicate Values
对于我大学的 Cryptographie 课程,我需要比较许多保存在数组中的 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 中的这些行做一些事情:
假设这个包含 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
但说实话 - 我不明白为什么这样快得多。
你的超级慢,因为它有 O n**2
嵌套 while
循环的复杂性。您正在为每个元素遍历整个数组。我在这里向您展示的方法只是在整个列表上循环一次 -- 而不是 300 万次!
对于我大学的 Cryptographie 课程,我需要比较许多保存在数组中的 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 中的这些行做一些事情:
假设这个包含 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
但说实话 - 我不明白为什么这样快得多。
你的超级慢,因为它有 O n**2
嵌套 while
循环的复杂性。您正在为每个元素遍历整个数组。我在这里向您展示的方法只是在整个列表上循环一次 -- 而不是 300 万次!