我将图像编码成一维颜色数组(为简单起见,这里用字母表示):
[A, B, C, D,
E, F, G, H,
I, J, K, L,
M, N, O, P]
但是由于我使用的库的限制,每个图像必须在maxElements
个项目和方块下。所以我需要做的是提取" sector"从那个图像,所以我可以分别迭代它们。 maxElements = 4
的示例:
[A, B, [C, D,
E, F] G, H]
[I, J, [K, L,
M, N] O, P]
如果有余数,则应将其存储在较小的数组中。 side = 3
,maxElements = 4
的示例:
[A, B, C, [[A, B, [C,
D, E, F, -> D, E] F]
G, H, I] [G, H] [I]]
请注意,阵列是在第3列切割的,因为如果它的尺寸超过2x2,则会违反maxElements
。
然而,一个额外的挑战是我无法访问此图片,直到为时已晚,但我确实有图像的侧(如方方面)和每个扇区的最大元素数。所以我想要做的是为数组中的每个像素生成一个索引数组。
所以我有1D数组中每行的长度和行数(都是 side ),我需要为要获取的数据生成一个索引数组阵列。 side = 4
,maxElements = 4
的示例输出:
[[1, 2, 5, 6], [3, 4, 7, 8], [9, 10, 13, 14], [11, 12, 15, 16]]
也许我没有睡觉太多时间,但我无法解决这个问题。
答案 0 :(得分:0)
这是一个粗略的想法:
要访问2D数组的1D表示中的(x,y)
元素: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] };
}
}
这是草图。要处理side = 3 maxElements = 4
案例,您需要检查边界,以检查(x+1)<W
和(y+1)<H
。这意味着,有四种情况:
bool xi = (x+1)<W, yi = (y+1)<H;
if (xi && yi) // both within range
output[...] = new int[] { arr[...], arr[...], arr[...], arr[...] };
if (!xi && yi) // only y within range
output[...] = new int[] { arr[...], arr[...] };
if (xi && !yi) // only x within range
output[...] = new int[] { arr[...], arr[...] };
else // both out of range
output[...] = new int[] { arr[...] };
答案 1 :(得分:0)
回到这个问题后,我找到了解决方案:
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;
}
使用以下示例:
var resultSectors = SectorizeMap(Enumerable.Range(0, 36), 6, 4);
Console.WriteLine(string.Join(", ",
resultSectors.Select(sec => string.Format("[{0}]",
string.Join(", ", sec)))));
我们开始接收输入数组,宽度(以2D表示)和每个扇区的最大项目数。