문제

데이터를 로드해야 하는 2차원 배열이 있습니다.데이터의 너비(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개 요소로 구성된 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();

나는 일반적으로 이런 종류의 작업(List, ArrayList 등)에 더 좋은 컬렉션을 사용하고 작업이 끝나면 (정말 필요한 경우) T[,]로 캐스팅합니다.

배열을 최대 크기(float[999,22] )로 미리 할당하거나 다른 데이터 구조를 사용해야 합니다.

즉석에서 복사/크기 조정이 가능할 것 같아요 ..(하지만 내 생각에는 당신이 원하지 않을 것 같아요)

나는 목록이 합리적이라고 생각합니다.

System.Collections의 2차원 ArrayList를 사용할 수도 있습니다. 즉, ArrayList를 만든 다음 그 안에 다른 ArrayList를 넣습니다.이렇게 하면 필요한 동적 크기 조정이 제공되지만 약간의 오버헤드가 발생합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top