C# 我需要使用大尺寸的阵列

C# 我需要使用大尺寸的阵列,c#,C#,我的要求是在长度为10^15的整数数组中找到一个重复的数字。 我需要一次找到一个副本。我知道从数组中查找重复数字的方法(逻辑),但如何处理如此大的数字。您可以用常规方式声明它:new int[10000000000000]。但是,这只适用于64位机器;在32位机器上存储的最大数据量略高于2GB 实际上,您将无法将整个阵列存储在内存中。您需要想出一种方法,将其生成为较小的块,并单独检查这些块 数组中的数据是什么?也许你不需要一次就完成。或者您可以将数据存储在文件中。您将需要不同的数据结构。我怀疑要

我的要求是在长度为10^15的整数数组中找到一个重复的数字。
我需要一次找到一个副本。我知道从数组中查找重复数字的方法(逻辑),但如何处理如此大的数字。

您可以用常规方式声明它:
new int[10000000000000]
。但是,这只适用于64位机器;在32位机器上存储的最大数据量略高于2GB

实际上,您将无法将整个阵列存储在内存中。您需要想出一种方法,将其生成为较小的块,并单独检查这些块


数组中的数据是什么?也许你不需要一次就完成。或者您可以将数据存储在文件中。

您将需要不同的数据结构。我怀疑要求不是真的使用数组-我希望不是,因为数组只能容纳
Int32.MaxValue
元素,即2147483647。。。远低于10^15。即使在64位机器上,我相信CLR也要求数组最多包含这么多元素。(例如,请参阅文档-尽管可以将边界指定为64位整数,但如果它们真的那么大,它将抛出异常。)

现在,如果您能解释真正的需求是什么,我们很可能能够建议其他数据结构

如果这是一个理论问题,而不是一个实际问题,如果你能告诉我们这些约束条件,这将是有益的


例如,如果您有足够的内存来存储数组本身,那么请求2^24字节来存储您已经看到的数字(每个值一位)并不会要求太多。当然,这是假设值本身是32位整数。从空数组开始,为找到的每个数字设置相关位。如果您发现要设置一个已设置的数组,那么您已经找到了第一个副本。

您不能声明大于Int32.MaxValue(2^31,或大约2*10^9)的数组,因此,您必须将数组链接在一起,或者使用
列表来保存所有值。

无论数组大小如何,您的算法都应该是相同的。当然,你得到的最佳时间复杂度必须是(理想情况下)
O(n)

考虑以下算法的伪代码:

  • 创建一个容量等于数组中数字范围的
    HashSet
  • 循环数组中的每个数字,并检查它是否已存在于哈希集中。
    • 如果否,请立即将其添加到哈希集
    • 如果是,您已找到一个副本

  • 这里的内存使用远不是微不足道的,但是如果你想提高速度,它可以完成这项工作。

    一个10^15个整数的数组需要超过1 PB的存储空间。您说过它可以在一次传递中完成,因此不需要存储所有数据。但是,即使读取这么多的数据也需要花费大量的时间


    但是等一下,如果这些数字是整数,它们就属于某个范围,比如N=2^32。因此,您只需搜索最多N+1个数字即可找到重复的数字。现在这是可行的。

    您可以使用长度为2^(32-5)=0x0800000的位向量数组

    这对于每个可能的int32数字都有一个位

    注意:easy solution(位数组)不支持adecuate构造函数

    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;
        }
    }
    
    问题:

    1) 是数组中的项数10^15

    2) 或者项目的值可以是10^15

    如果是#1:

    你从哪里弄来的核弹?如果它是一个文件,你可以通过它的步骤

    是否有超过2147483647个唯一编号

    如果是#2:

    int64可以处理这个数字

    如果其#1和#2:

    是否有超过2147483647个唯一编号


    如果唯一数字少于2147483647,您可以使用列表,无需执行任何操作。根据定义,将存在重复,因为2^32<10^15-没有足够的数字来唯一填充10^15数组。:)


    现在,如果有一个额外的要求,你知道哪里的副本。。。这是另一个故事,但它不在原始问题中。

    听起来像是家庭作业……:/我可能错了,那是3700 TB的数据!你想说:arr=newint[10pow15];查找重复(arr)?根据你提出的其他问题,这真的是你想要的吗?你的目标是什么,也许可以用不同的方法来解决。你知道数组中的数字吗?如果是家庭作业,答案将比“用10^15个元素组成一个数组”更微妙。在这种情况下,我并不担心这是家庭作业,因为这个问题与其他问题不同:“我如何做家庭作业”更像是“我如何实现我已经拥有的这个概念”。因此,我认为这是一个非常好的问题。在时间和内存使用之间的一个更好的权衡(给你时间
    O(n log n)
    )是对数组进行排序(快速排序),并寻找两个相同的连续数字。也许在时间上是禁止的,但我怀疑…@Nolorin:是的,这可能是最好的速度/内存权衡。顺便说一下,
    HashSet
    的容量不能超过32位整数的大小。它被输入到
    Int32
    @are:我们不知道数字的范围。。。
    HashSet
    仅与数字范围(可能是整个32位整数集)一样大。听起来OP从一开始就采取了错误的方法,嗯。最坏的情况是每个数字都不同,这意味着有
    n
    唯一的数字。但你们是对的,有些东西告诉我这里的一般方法是错误的(从OP上看)。我认为这个列表也行不通
    List
    使用
    System.Int32
    来存储它的索引/计数/容量等…我以为你只能在.Net中声明2GB的数据(包括64位)?不能在我的机器上试你会得到我的