我有一个二维数组,需要将数据加载到其中。我知道数据的宽度(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[,];

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

谢谢,基思

有帮助吗?

解决方案

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

通常,您会选择集合类之一 - 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]

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

其他提示

如果不显式或隐式地在初始化数组时指定一组文字值,则无法在 .NET 中创建数组(而不是声明对它的引用,这就是您在示例中所做的) 。(例如。int[,] array4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };)

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

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

您会注意到这里我使用了锯齿状数组(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();

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

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top