从不需要的值中修剪一个2d的int数组

时间:2014-11-01 16:22:38

标签: c# algorithm

我有一个像这样声明的数组:

int[,] binaryzacja = new int[bmp2.Width, bmp2.Height];

它的尺寸是图片的尺寸(通常是200x200)。黑色像素由1表示。所有其他像素由0表示。

假设我的数组看起来像这样:

0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 1 0 1 1 1 0
0 1 1 1 0 0 0
0 0 1 1 0 0 0
0 0 0 0 0 0 0

我想删除仅包含0的所有行列。

所以,如果我的示例数组是7列,6行;我想要一个新的数组,它将是5列,3行,看起来像这样:

1 0 1 1 1
1 1 1 0 0
0 1 1 0 0 

3 个答案:

答案 0 :(得分:3)

您可以将[,]转换为List

var list = new List<List<int>>();

for (var i = 0; i < binary.GetLength(0); i++ )
{
    var row = new List<int>();
    for(var j = 0; j < binary.GetLength(1); j++)
        row.Add(binary[i, j]);
    list.Add(row);
}

然后删除全部为零的行和列:

// Remove the rows
list = list.Where(row => row.Contains(1)).ToList();
// Reverse the matrix and apply the same procedure to remove the columns
list = Transpose(list);
list = list.Where(row => row.Contains(1)).ToList();
// Get back the original order of the rows and columns
list = Transpose(list);

static List<List<int>> Transpose(List<List<int>> input)
{
    return input.ElementAt(0).Select((item, index) => 
        {
            var row = new List<int>{input[0][index]};
            input.ForEach(el => row.Add(el.ElementAt(index)));
            return row;
            }).ToList();
        }
}

然后将结果列表转换回[,]

int[,] binaryResult = new int[list.Count(), list.First().Count()];

for (int i = 0; i < binaryResult.GetLength(0); i++)
    for (int j = 0; j < binaryResult.GetLength(1); j++)
        binaryResult[i, j] = list.ElementAt(i).ElementAt(j);

当然,您应该将这些提取到方法中。

答案 1 :(得分:1)

没有花哨的东西:

int width = binaryzacja.GetLength(0);
int height = binaryzacja.GetLength(1);

int newWidth = width;
int newHeight = height;

int x, y, x2, y2;

for (y = 0; y < height; y++)
{
    if (IsRowEmpty(binaryzacja, y)) newHeight--;
}

for (x = 0; x < width; x++)
{
    if (IsColumnEmpty(binaryzacja, x)) newWidth--;
}

int[,] binaryzacja2 = new int[newWidth, newHeight];


// copy to new array
for (y2 = y = 0; y < height; y++)
{
    if (!IsRowEmpty(binaryzacja, y))
    {
        for(x = x2 = 0; x < width; x++)
        {
            if (!IsColumnEmpty(binaryzacja, x))
            {
                binaryzacja2[x2, y2] = binaryzacja[x, y];
                x2++;
            }
        }
        y2++;
    }
}



bool IsRowEmpty(int[,] array, int y)
{
    for (int x = 0; x < array.GetLength(0); x++)
    {
        if (array[x, y] != 0) return false;
    }
    return true;
}

bool IsColumnEmpty(int[,] array, int x)
{
    for (int y = 0; y < array.GetLength(1); y++)
    {
        if (array[x, y] != 0) return false;
    }
    return true;
}

-----新版本:

int width = binaryzacja.GetLength(0);
int height = binaryzacja.GetLength(1);

int newWidth = width;
int newHeight = height;

int[] keepRows = new int[height];
int[] keepColumns = new int[width];

int x, y, x2, y2;
int i;

for (i = y = 0; y < height; y++)
{
    if (IsRowEmpty(binaryzacja, y)) newHeight--;
    else
    {
        keepRows[i] = y;
        i++;
    }
}

for (i = x = 0; x < width; x++)
{
    if (IsColumnEmpty(binaryzacja, x)) newWidth--;
    else
    {
        keepColumns[i] = x;
        i++;
    }
}

int[,] binaryzacja2 = new int[newWidth, newHeight];

// copy to new array
for (y2 = y = 0; y < height; y++)
{
    if(y == keepRows[y2])
    {
        for (x2 = x = 0; x < width; x++)
        {
            if(x == keepColumns[x2])
            {
                binaryzacja2[x2, y2] = binaryzacja[x, y];
                x2++;
            }
        }
        y2++;
    }
}

答案 2 :(得分:0)

遍历行,并在某种数组中跟踪空的行。 对列做同样的事情。

使用此信息,创建适当行和列的新数组。 循环使用双循环。如果i等于数组中的一行,或者j等于列中的行,则跳过该值。