Pergunta

Eu tenho uma matriz bidimensional na qual preciso carregar dados.Conheço a largura dos dados (22 valores) mas não sei a altura (estimada em torno de 4.000 registros, mas variável).

Eu tenho declarado da seguinte forma:

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

Isso causa uma NullReferenceException, então quando tento inicializá-lo assim:

_calibrationSet = new float[,];

Recebo uma mensagem "A criação de array deve ter tamanho de array ou inicializador de array".

Obrigado Keith

Foi útil?

Solução

Você não pode usar uma matriz.Ou melhor, você precisaria escolher um tamanho e, se precisasse de mais, teria que alocar um novo array maior, copiar os dados do antigo para o novo e continuar como antes (até você excede o tamanho do novo...)

Geralmente, você usaria uma das classes de coleção - ArrayList, List<>, LinkedList<>, etc.- qual deles depende muito do que você procura;List fornecerá o que há de mais próximo do que descrevi inicialmente, enquanto LinkedList<> evitará o problema de realocações frequentes (ao custo de acesso mais lento e maior uso de memória).

Exemplo:

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]

Ah, e vale a pena notar (como Grauenwolf fiz), que o que estou fazendo aqui não fornece a mesma estrutura de memória que um único array multidimensional daria - nos bastidores, é um array de referências a outros arrays que realmente contêm os dados.Isso acelera bastante a construção do array, tornando a realocação mais barata, mas pode ter um impacto na velocidade de acesso (e, claro, no uso de memória).Se isso é um problema para você, depende muito do que você fará com os dados depois de carregados...e se existem duzentos registros ou dois milhões de registros.

Outras dicas

Você não pode criar um array no .NET (em vez de declarar uma referência a ele, que foi o que você fez no seu exemplo) sem especificar suas dimensões, seja explicitamente ou implicitamente, especificando um conjunto de valores literais ao inicializá-lo .(por exemplo.int[,] matriz4 = { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };)

Você precisa usar uma estrutura de dados de tamanho variável primeiro (uma lista genérica de matrizes 1-d de 22 elementos seria a mais simples) e, em seguida, alocar sua matriz e copiar seus dados nela após a conclusão da leitura e você saber quantas linhas você precisa.

Eu apenas usaria uma lista e depois converteria essa lista em um array.

Você notará aqui que usei um array irregular (float[][]) em vez de um array quadrado (float [,]).Além de ser a forma “padrão” de fazer as coisas, deveria ser muito mais rápida.Ao converter os dados de uma lista em um array você só precisa copiar os ponteiros [calibrationRow].Usando uma matriz quadrada, você teria que copiar [calibrationRow] x [SensorCount] floats.

        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();

Eu geralmente uso as coleções mais legais para esse tipo de trabalho (List, ArrayList etc.) e depois (se realmente necessário) converto em T[,] quando terminar.

você precisaria pré-alocar a matriz para um tamanho máximo (float[999,22] ) ou usar uma estrutura de dados diferente.

eu acho que você pode copiar / redimensionar na hora ..(mas eu não acho que você gostaria)

acho que a lista parece razoável.

Você também pode usar um ArrayList bidimensional (de System.Collections) - você cria um ArrayList e coloca outro ArrayList dentro dele.Isso lhe dará o redimensionamento dinâmico necessário, mas à custa de um pouco de sobrecarga.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top