简体   繁体   English

具有非零下限的二维数组的子数组

[英]SubArray of a 2d array with non-zero lower bounds

The extension :扩展名:

public static T[,] SubArray<T>(this T[,] values, int row_min, int row_max, int col_min, int col_max)
{
    int num_rows = row_max - row_min + 1;
    int num_cols = col_max - col_min + 1;
    T[,] result = new T[num_rows, num_cols];

    int total_cols = values.GetUpperBound(1) + 1;
    int from_index = row_min * total_cols + col_min;
    int to_index = 0;
    for (int row = 0; row <= num_rows - 1; row++)
    {
        Array.Copy(values, from_index, result, to_index, num_cols);
        from_index += total_cols;
        to_index += num_cols;
    }

    return result;
}

work well for 2D arrays arrays whose GetLowerBound(0) and GetLowerBound(1) are equal to zero.适用于GetLowerBound(0)GetLowerBound(1)等于GetLowerBound(0)二维数组。 For instance if例如如果

int[,] arr1 = new int[5, 4];
for (int i = 0; i < 5; ++i)
{
    for (int j = 0; j < 4; ++j)
    {
        arr1[i, j] = i + j;
    }
}

var arr1sub = arr1.SubArray(2, 3, 1, 3);

Then arr1sub is the 2d array with 2 rows and 3 colums (boths with indexes starting at 0)然后arr1sub是具有 2 行和 3 列的二维数组(两者的索引都从 0 开始)

3  4  5
5  6  7

Now if I look at the case where the initial array as indexes not starting at zero :现在,如果我查看初始数组作为索引不从零开始的情况:

int[,] arr2 = (int[,])Array.CreateInstance(typeof(int), new int[] { 5, 4 }, new int[] { 3, 1 });
for (int i = arr2.GetLowerBound(0); i <= arr2.GetUpperBound(0); ++i)
{
    for (int j = arr2.GetLowerBound(1); j <= arr2.GetUpperBound(1); ++j)
    {
        arr2[i, j] = i - arr2.GetLowerBound(0) + j - arr2.GetLowerBound(1);
    }
}
var arr2sub = arr2.SubArray(5, 6, 2, 4);

the last line of previous code snippet will trigger an exception in the SubArray extension function at the line前面代码片段的最后一行将在该行的SubArray扩展函数中触发异常

Array.Copy(values, from_index, result, to_index, num_cols);

for row equal to zero.对于row等于零。

I understand of the 2d array arr1 (with zero based indexes) is layed out in memory but not how the 2d array arr2 (with non-zero-based indexes) is layed out in memory, hence my use of Array.Copy must be wrong in this case, but I don't see why.我了解二维数组arr1 (具有基于零的索引)在内存中布局,但不了解二维数组arr2 (具有非基于零的索引)在内存中的Array.Copy ,因此我对Array.Copy使用一定是错误的在这种情况下,但我不明白为什么。

You are not calculating total_cols and from_index correctly.您没有正确计算total_colsfrom_index

public static T[,] SubArray<T>(this T[,] values, int row_min, int row_max, int col_min, int col_max)
{
    int num_rows = row_max - row_min + 1;
    int num_cols = col_max - col_min + 1;
    T[,] result = new T[num_rows, num_cols];

    int total_cols = values.GetLength(1);
    int from_index = (row_min - values.GetLowerBound(0)) * total_cols + (col_min - values.GetLowerBound(1)) + values.GetLowerBound(0);
    int to_index = 0;
    for (int row = 0; row <= num_rows - 1; row++)
    {
        Array.Copy(values, from_index, result, to_index, num_cols);
        from_index += total_cols;
        to_index += num_cols;
    }

    return result;
}

total_cols is the obvious one; total_cols是显而易见的; as for from_index , I cannot find any documentation on that, but it would appear that sourceIndex in Array.Copy starts counting from sourceArray.GetLowerBound(0) and not from zero, which is not necessarily immediately obvious given that this index keeps growing across rows and columns.至于from_index ,我找不到任何关于它的文档,但看起来sourceIndex中的Array.CopysourceArray.GetLowerBound(0)开始计数,而不是从零开始计数,鉴于此索引在行间不断增长,这不一定立即显而易见和列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM