C# 将一维编码的二维阵列划分为扇区

C# 将一维编码的二维阵列划分为扇区,c#,arrays,algorithm,multidimensional-array,C#,Arrays,Algorithm,Multidimensional Array,我将图像编码为1D颜色数组(为了简单起见,这里用字母表示): 但由于我使用的库的限制,每个图像都必须在maxElements项下,并且是正方形。所以我需要做的是从图像中提取“扇区”,这样我可以分别迭代它们。maxElements=4示例: [A, B, [C, D, E, F] G, H] [I, J, [K, L, M, N] O, P] [A, B, C, [[A, B, [C, D, E, F, -> D, E] F] G, H, I]

我将图像编码为1D颜色数组(为了简单起见,这里用字母表示):

但由于我使用的库的限制,每个图像都必须在
maxElements
项下,并且是正方形。所以我需要做的是从图像中提取“扇区”,这样我可以分别迭代它们。
maxElements=4
示例:

[A, B, [C, D,
 E, F]  G, H]
[I, J, [K, L,
 M, N]  O, P]
[A, B, C,      [[A, B, [C,
 D, E, F,  ->    D, E]  F]
 G, H, I]       [G, H] [I]]
[[1, 2, 5, 6], [3, 4, 7, 8], [9, 10, 13, 14], [11, 12, 15, 16]]
如果有余数,则应将其存储在较小的数组中。
side=3
maxElements=4
示例:

[A, B, [C, D,
 E, F]  G, H]
[I, J, [K, L,
 M, N]  O, P]
[A, B, C,      [[A, B, [C,
 D, E, F,  ->    D, E]  F]
 G, H, I]       [G, H] [I]]
[[1, 2, 5, 6], [3, 4, 7, 8], [9, 10, 13, 14], [11, 12, 15, 16]]
请注意,数组在第3列被剪切,因为如果其尺寸超过2x2,它将违反
maxElements

然而,另一个挑战是,我直到太晚才可以访问此图像,但我确实有图像的侧面(如正方形侧面)和每个扇区的最大元素数。所以我要做的是为数组中的每个像素生成一个索引数组

因此,我有1D数组中每一行的长度和行数(都是边),我需要生成一个索引数组,该数组将获得索引。
side=4
maxElements=4
的输出示例:

[A, B, [C, D,
 E, F]  G, H]
[I, J, [K, L,
 M, N]  O, P]
[A, B, C,      [[A, B, [C,
 D, E, F,  ->    D, E]  F]
 G, H, I]       [G, H] [I]]
[[1, 2, 5, 6], [3, 4, 7, 8], [9, 10, 13, 14], [11, 12, 15, 16]]
也许我没有睡眠的时间太多了,但我无法找到解决办法。

这里有一个粗略的想法:

要访问二维数组的一维表示形式中的
(x,y)
th元素:
x+y*H
。 假设我们要访问数组中的x=1和y=2(W=4,H=4):
arr[1+2*4]==arr[9]=J

因为我们知道如何通过坐标访问元素,所以我们可以使用循环:

for (int x = 0; x < W; x += 2) {
  for (int y = 0; y < H; y += 2)
    output[(x/2) + (y/2)*(H/2)] = new int[] { arr[x + y*H],     arr[(x+1) + y*H], 
                                          arr[x + (y+1)*H], arr[(x+1) + (y+1)*H] };
  }
}

回到这个问题后,我找到了一个解决方案:

public static List<List<int>> SectorizeMap<T>(IEnumerable<T> input, int width, int maxPerSector) {
    var sectorSide = (int)Math.Sqrt(maxPerSector);
    var widthSectors = (int)Math.Ceiling((float)width / sectorSide);
    var resultSectors = new List<List<int>>();

    for (var i = 0; i < input.Count(); i++) {
        var x = i % width;
        var y = i / width;
        var sectorX = x / sectorSide;
        var sectorY = y / sectorSide;
        var sectorIndex = sectorY * widthSectors + sectorX;
        if (resultSectors.Count <= sectorIndex) {
            resultSectors.Add (new List<int> ());
        }
        resultSectors[sectorIndex].Add(i);
    }
    return resultSectors;
}
工作原理 我们开始接收输入数组、它的宽度(当用2D表示时)和每个扇区的最大项数

  • 由于扇区是方形的,因此取每个扇区的最大项目数的根,并将其用作扇区两侧的尺寸
  • 计算一行中适合的扇区数
  • 迭代输入:
  • 将元素的索引解码为(x,y)对
  • 将扇形(x,y)对指定给这些坐标
  • 将扇区坐标转换为索引
  • 将当前元素的索引添加到我们计算位置的扇区,必要时创建它
  • 返回扇区列表

  • [i,i+1,i+side,i+1+side]
    对于(i=0;i
    为什么在最后一个示例中,我们不能将最后一个数组划分为
    [C,F,i]
    ?因为边是3,maxElements是4,所以这应该是有效的?@PhamTrung这会更好,但我想它可能更复杂?