我的要求是在长度为10 ^ 15的整数数组中找到重复的数字。 我需要在一次通过中找到一份副本。我知道从数组中找到重复数字的方法(逻辑),但我怎样才能处理如此大的数字。
答案 0 :(得分:7)
一个10 ^ 15整数的数组需要超过1 PB的存储空间。你说它可以一次完成,所以不需要存储所有数据。但即使阅读这些数据也需要很多的时间。
但等等,如果数字是整数,它们会落入一定的范围,比方说N = 2 ^ 32。因此,您只需要搜索最多N + 1个数字即可找到重复数据。现在这是可行的。
答案 1 :(得分:4)
您可以使用长度为= 2 ^(32-5)= 0x0800000
的BitVector数组每个有效的int32号都有一点。
注意:简易解决方案(BitArray)不支持适当的构造函数。
BitVector32[] bv = new BitVector32[0x8000000];
int[] ARR = ....; // Your array
foreach (int I in ARR)
{
int Element = I >> 5;
int Bit = I & 0x1f;
if (bv[Element ][Bit])
{
// Option for First Duplicate Found
}
else
{
bv[I][Bit] = true;
}
}
答案 2 :(得分:1)
您需要不同的数据结构。我怀疑要求不是真的使用数组 - 我希望不会,因为数组只能容纳Int32.MaxValue
个元素,即2,147,483,647 ...远小于10 ^ 15。即使在64位机器上,我相信CLR要求阵列最多包含那么多元素。 (例如,请参阅Array.CreateInstance
的文档 - 即使您可以将边界指定为64位整数,如果它们实际上很大,它也会抛出异常。)
现在,如果您可以解释真实要求是什么,我们很可能会建议其他数据结构。
如果这是一个理论问题而不是一个实际问题,那么如果你能告诉我们这些限制也会有所帮助。
例如,如果你有足够的内存用于数组本身,那么要求2 ^ 24个字节来存储你已经看过的数字(每个值一位)并不需要太多。当然,这假设值本身是32位整数。从空数组开始,并为找到的每个数字设置相关位。如果您发现即将设置已设置的那个,那么您已找到第一个副本。
答案 3 :(得分:0)
您可以按正常方式声明:new int[1000000000000000]
。但是这只适用于64位机器;你可以期望在32位机器上存储的最大值是2GB以上。
实际上,您将无法将整个阵列存储在内存中。你需要想出一种在较小的块中生成它的方法,并单独检查这些块。
阵列中的数据是什么?也许你不需要一次性生成它。或者也许你可以将数据存储在一个文件中。
答案 4 :(得分:0)
您不能声明大小大于Int32.MaxValue(2 ^ 31,或大约2 * 10 ^ 9)的数组,因此您必须将数组链接在一起或使用List<int>
来保存所有数组价值观。
答案 5 :(得分:0)
无论数组大小如何,您的算法都应该是相同的。你得到的最佳时间复杂度当然是(理想情况下)O(n)
。
考虑以下算法的伪代码:
HashSet<int>
容量。这里的内存使用远非微不足道,但如果你想要速度,它就能完成这项工作。
答案 6 :(得分:0)
问题,
1)是数组10 ^ 15
中的项目数2)或者物品的价值可以是10 ^ 15?
如果是#1:
你从哪里拉数钱?如果它是一个文件,你可以单步执行它。
是否有超过2,147,483,647个唯一数字?
如果是#2:
int64可以处理数字
如果#1和#2:
是否有超过2,147,483,647个唯一数字?
如果少于2,147,483,647个唯一数字,您可以使用List&lt; bigint&gt;
答案 7 :(得分:0)
你不需要做任何事情。根据定义,将存在重复,因为2 ^ 32&lt; 10 ^ 15 - 没有足够的数字来唯一地填充10 ^ 15阵列。 :)
现在,如果还有一个额外的要求,你知道哪里重复是......那是另一个故事,但它不是原来的问题。