2

假设我想在一个类中存储无限数量的元素,就像 Excel 对工作表的数量所做的那样(受计算机内存的限制)。

保存用于获取元素的索引的方式或数字类型是什么?

4

7 回答 7

6

如果你想存储一个任意大的整数,你可以使用BigInteger.

public BigInteger Index{ get; set; }

请注意,您必须首先添加对System.Numericsdll 的引用。

它与 .NET Framework 中的其他整数类型不同,后者具有由其MinValueMaxValue属性指示的范围。

因为它没有上限或下限,所以任何导致值增长过大OutOfMemoryException的操作都可以抛出。BigInteger

于 2013-04-03T14:52:04.357 回答
1

如果你想滚动你自己的集合,你可以使用Indexer。以下简单示例可以处理 100 个元素,但您可以使用 List 或其他机制将其扩展到所需的任意数量的元素:

class SampleCollection<T>
{
    // Declare an array to store the data elements. 
    private T[] arr = new T[100];

    // Define the indexer, which will allow client code 
    // to use [] notation on the class instance itself. 
    public T this[int i]
    {
        get
        {
            // This indexer is very simple, and just returns or sets 
            // the corresponding element from the internal array. 
            return arr[i];
        }
        set
        {
            arr[i] = value;
        }
    }
}

此类显示客户端代码如何使用索引器:

class Program
{
    static void Main(string[] args)
    {
        // Declare an instance of the SampleCollection type.
        SampleCollection<string> stringCollection = new SampleCollection<string>();

        // Use [] notation on the type.
        stringCollection[0] = "Hello, World";
        System.Console.WriteLine(stringCollection[0]);
    }
}
// Output: 
// Hello, World.

使用 anint作为索引器参数将使您可以访问大约 20 亿个离散元素。如果您需要更多,则必须使用long或任意精度类型,BigInt如索引器参数。

于 2013-04-03T14:50:47.130 回答
1

Tim-Schmelter 和 Joseph Lee 为您提供了很好的答案。但考虑到它们是最大化价值的好答案。但是,请考虑实现的细节:如果您的数据结构只有一个字节,那么在考虑任何其他因素(数据结构等)之前,即使是 ULong 也可以索引超过 EB 的值。

于 2013-04-03T15:11:32.887 回答
0

任何数值类型的变量都是有限的。我所知道的最大的是 ULong(0 到 18,446,744,073,709,551,615)。如果你有比这更多的元素,你就有麻烦了......

于 2013-04-03T14:54:43.920 回答
0

在 .Net 中,任何特定对象都有 2Gb 的限制。这意味着,例如,byte[]数组索引不能大于int.MaxValue- 实际上它甚至更小。

因此,您可以轻松地将Int32==int用于任何索引,或者您应该仔细考虑您的数据结构。

于 2013-04-03T14:56:54.830 回答
0

要索引仅受可用系统内存限制的项目集合,您可能可以使用long. 该范围足以唯一地寻址存储库的各个位,该存储库的大小几乎是TACC Stampede 的14PB 驱动器空间大小的 150 倍(或超过其 207TB 主存储器库大小的 10000 倍)。

于 2013-04-03T14:59:56.957 回答
0

根据 Tim Schmelter 的回答:

public class BigList<T>
{
    public Object[] internalArray = new Object[Int16.MaxValue];

    public T this[BigInteger i]
    {
        get
        {
            if (i < Int16.MaxValue-1)
            {
                return (T)internalArray[(int)i];
            }
            else
            {
                i = i - int.MaxValue;
                BigList<T> following = (BigList<T>)internalArray[Int16.MaxValue-1];
                if (following != null)
                {
                    return following[i];
                }
                else
                {
                    throw new KeyNotFoundException();
                }
            }
        }
        set
        {
            if (i < Int16.MaxValue-1)
            {
                internalArray[(int)i] = value;
            }
            else
            {
                i = i - int.MaxValue;
                BigList<T> following = (BigList<T>)internalArray[Int16.MaxValue-1];
                if (following == null)
                {
                    following = new BigList<T>();
                    internalArray[Int16.MaxValue - 1] = following;
                }
                following[i] = value;
            }
        }
    }
}

并开始单元测试:

[Test]
public void BigListTest()
{
    BigList<string> test = new BigList<string>();
    var bigIndex = new BigInteger(int.MaxValue);
    string value = "test";
    bigIndex *= 2;
    test[bigIndex] = value;
    Assert.AreEqual(test[bigIndex],value);
}
于 2013-04-03T15:26:53.563 回答