如何扩展多维数组?

时间:2014-09-15 21:21:23

标签: c# arrays

它有一个数组CriticalArray,可以在整个应用程序中使用,可能由多个线程使用。 有时需要根据用户操作扩展此数组的大小。当需要大幅增加大小时,下面的代码需要几分钟才能执行。 有没有办法以更有效的方式扩展数组的大小?

Data[,] CriticalArray = new Data[COLS,ROWS];

通常值为COLS = 50且ROWS = 3000.展开尺寸时,尺寸可变为50,90000。

这是导致延迟的扩展代码:

Data[,] TempCriticalArray = new Data[COLS, DELTA + ROWS];

for (int i = 0; i < COLS; i++)
  for (int j = 0; j < ROWS; j++)
    TempCriticalArray[i, j] = CriticalArray[i, j];

CriticalArray = TempQuoteStore;

2 个答案:

答案 0 :(得分:2)

正如您可能已经注意到的那样,通常的Array.Resize对多维数组不起作用。

由于您没有更改列数,因此可以使用Array.Copy(请注意,实例方法array.CopyTo不支持多维数组)。

来自MSDN的注释:

  

在多维数组之间进行复制时,数组的行为类似于   长一维数组,行(或列)所在的位置   概念上是端到端的。例如,如果数组有三行   (或列)每个有四个元素,复制六个元素   数组的开头将复制第一行的所有四个元素   (或列)和第二行(或列)的前两个元素。

Data[,] CriticalArray = new Data[COLS,ROWS];
Data[,] TempCriticalArray = new Data[COLS, DELTA + ROWS];

Array.Copy(CriticalArray, TempCriticalArray, CriticalArray.Length);

CriticalArray = TempCriticalArray

这可能和复制数组在C#中的速度一样快,但是如果你必须移动10 GB的数据,你必须要有一些延迟...

如果可能,您还可以考虑使用其他数据结构或更改设计,以免需要同时加载多个项目。

答案 1 :(得分:0)

您还可以更改数据结构,这样您就不需要复制数据,只需将数据附加到其中即可。这意味着您需要自己实现索引器,这可能会减慢索引访问速度,但是在向矩阵中添加行同时保持列数固定时会更快。 这是一个LinkedList的草稿,它显示了这个想法,虽然一些边界错误可能仍在其中:

class LinkedMatrix<T>
{
    int LowerY;
    int UpperY;

    public int TotalColums
    {
        get;
        private set;
    }

    LinkedMatrix<T> Next;

    T[,] InternalArray;

    public LinkedMatrix(int rows, int cols)
    {
        InternalArray = new T[rows, cols];
        UpperY = rows;
        TotalColums = cols;
    }

    private LinkedMatrix(int lowerY, int addedRows, int colums)
    {
        InternalArray = new T[addedRows, colums];
        LowerY = lowerY;
        UpperY = LowerY + addedRows;
    }

    public void AppendRows(int addedRows)
    {
        LinkedMatrix<T> LastNotNull = this;
        while( LastNotNull.Next != null )
        {
            LastNotNull = LastNotNull.Next;
        }

        LastNotNull.Next = new LinkedMatrix<T>(LastNotNull.UpperY, addedRows, this.TotalColums);
    }

    public T this[int y, int x]
    {
        get
        {
            if( y >= UpperY  )
            {
                if( Next != null)
                {
                    return Next[y, x];
                }
                else
                {
                    throw new IndexOutOfRangeException();
                }
            }
            else if( y >= LowerY )
            {
                return InternalArray[y - LowerY, x];
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }

        set
        {
            if (y >= UpperY)
            {
                if (Next != null)
                {
                    Next[y,x] = value;
                }
                else
                {
                    throw new IndexOutOfRangeException();
                }
            }
            else if (y >= LowerY)
            {
                InternalArray[y - LowerY, x] = value;
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
    }
}


class Program
{
    static void Main(string[] args)
    {
        LinkedMatrix<string> matrix = new LinkedMatrix<string>(1, 1);
        matrix[0, 0] = "0,0";
        matrix.AppendRows(1);
        matrix[1, 0] = "1,0";
    }
}