8

我有一个二维数组,我需要将数据加载到其中。我知道数据的宽度(22 个值)但我不知道高度(估计大约 4000 条记录,但可变)。

我将其声明如下:

float[,] _calibrationSet;
    ....
int calibrationRow = 0;
While (recordsToRead)
{
  for (int i = 0; i < SensorCount; i++)
   {
     _calibrationSet[calibrationRow, i] = calibrationArrayView.ReadFloat();
   }
   calibrationRow++;
}

这会导致 NullReferenceException,所以当我尝试像这样初始化它时:

_calibrationSet = new float[,];

我得到一个“数组创建必须具有数组大小或数组初始值设定项”。

谢谢你,基思

4

6 回答 6

8

你不能使用数组。或者更确切地说,您需要选择一个大小,如果您最终需要更多,那么您将不得不分配一个新的更大的数组,将数据从旧数组复制到新数组中,然后像以前一样继续(直到你超过了新的大小......)

通常,您会选择其中一个集合类 - ArrayList、List<>、LinkedList<> 等 - 哪一个很大程度上取决于您要查找的内容;List 将为您提供最接近我最初描述的内容,而 LinkedList<> 将避免频繁重新分配的问题(以较慢的访问和更大的内存使用为代价)。

例子:

List<float[]> _calibrationSet = new List<float[]>();

// ...

while (recordsToRead)
{
    float[] record = new float[SensorCount];
    for (int i = 0; i < SensorCount; i++)
    {
        record[i] = calibrationArrayView.ReadFloat();
    }
    _calibrationSet.Add(record);
}

// access later: _calibrationSet[record][sensor]

哦,值得注意的是(正如Grauenwolf所做的那样),我在这里所做的并没有为您提供与单个多维数组相同的内存结构 - 在引擎盖下,它是对其他数组的引用数组实际上保存数据。通过使重新分配更便宜,这可以大大加快构建阵列的速度,但会影响访问速度(当然还有内存使用)。这对您来说是否是一个问题在很大程度上取决于加载数据后您将如何处理数据......以及是否有 200 条记录或 200 万条记录。

于 2008-09-08T20:23:58.133 回答
2

您不能在 .NET 中创建一个数组(与声明对它的引用相反,这就是您在示例中所做的)而不通过在初始化时指定一组文字值来显式或隐式指定其维度. (例如 int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };)

您需要首先使用可变大小的数据结构(22 元素一维数组的通用列表将是最简单的),然后在读取完成后分配您的数组并将数据复制到其中并且您知道有多少行你需要。

于 2008-09-08T20:24:20.677 回答
1

我只会使用一个列表,然后将该列表转换为一个数组。

您会注意到这里我使用了锯齿状数组 (float[][]) 而不是方形数组 (float [,])。除了作为“标准”的做事方式之外,它应该更快。将数据从列表转换为数组时,您只需复制 [calibrationRow] 指针。使用方形数组,您必须复制 [calibrationRow] x [SensorCount] 浮点数。

        var tempCalibrationSet = new List<float[]>();
        const int SensorCount = 22;
        int calibrationRow = 0;

        while (recordsToRead())
        {
            tempCalibrationSet[calibrationRow] = new float[SensorCount];

            for (int i = 0; i < SensorCount; i++)
            {
                tempCalibrationSet[calibrationRow][i] = calibrationArrayView.ReadFloat();
            } calibrationRow++;
        }

        float[][] _calibrationSet = tempCalibrationSet.ToArray();
于 2008-09-08T20:27:45.753 回答
0

我通常将更好的集合用于此类工作(List、ArrayList 等),然后(如果确实需要)在完成后转换为 T[,]。

于 2008-09-08T20:25:19.363 回答
0

您要么需要将数组预分配为最大大小 (float[999,22]),要么使用不同的数据结构。

我想您可以即时复制/调整大小..(但我认为您不想这样做)

我认为清单听起来很合理。

于 2008-09-08T20:26:46.520 回答
0

您还可以使用二维 ArrayList(来自 System.Collections)——您创建一个 ArrayList,然后将另一个 ArrayList 放入其中。这将为您提供所需的动态调整大小,但会产生一些开销。

于 2008-09-08T20:28:34.347 回答