我有一个二维数组,比如说
0 0 0 0 0
0 2 3 4 0
0 9 1 5 0
0 8 7 6 0
0 0 0 0 0
我需要得到与1相邻的所有数字(2,3,4,5,6,7,8,9)
有没有比这更不难看的解决方案:
topLeft = array[x-1][y-1]
top = array[x][y-1]
topRight = array[x+1][y-1]
# etc
谢谢!
发布于 2010-01-10 08:23:23
如果你不担心顺序,最干净的方法可能是使用几个循环:
result = new List<int>(8);
for (dx = -1; dx <= 1; ++dx) {
for (dy = -1; dy <= 1; ++dy) {
if (dx != 0 || dy != 0) {
result.Add(array[x + dx][y + dy]);
}
}
}
如果顺序很重要,您可以按您想要的顺序构造一个包含所有(dx,dy)的列表,然后对其进行迭代。
正如注释中指出的,您可能希望添加边界检查。你可以这样做(假设顺序并不重要):
List<int> result = new List<int>(8);
for (int dx = (x > 0 ? -1 : 0); dx <= (x < max_x ? 1 : 0); ++dx)
{
for (int dy = (y > 0 ? -1 : 0); dy <= (y < max_y ? 1 : 0); ++dy)
{
if (dx != 0 || dy != 0)
{
result.Add(array[x + dx][y + dy]);
}
}
}
发布于 2010-01-10 10:16:20
我可能会选择每个方向的dx,dy的常量列表,如下所示:
struct {
int dx;
int dy;
} directions[] = {{-1,-1,},{-1,0,},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
然后使用一个简单的循环遍历方向:
for (int i = 0; i < 8; i++) {
// use x + directions[i].dx;
// use y + directions[i].dy;
}
当然,您可以使用sizeof(directions) / sizeof(directions[1])
而不是上面的8
。
发布于 2010-01-10 18:46:01
就个人而言,循环比原始循环更丑陋。
topLeft = array[ x - 1 ][ y - 1 ]
top = array[ x ][ y - 1 ]
topRight = array[ x + 1 ][ y - 1 ]
midLeft = array[ x - 1 ][ y ]
midRight = array[ x + 1 ][ y ]
botLeft = array[ x - 1 ][ y + 1 ]
bot = array[ x ][ y + 1 ]
botRight = array[ x + 1 ][ y + 1 ]
但是没有指定你想要的值是什么-你在不同的方向上做的事情意味着你是否想要在单独的变量中使用这些值。
对于生活游戏风格的处理,您通常希望处理一个位模式,而不是单个值的数组,并且您可以使用累加器和临时函数一次仅水平扫描检查八个单元格中的三个。对于图形卷积,请使用具有3x3内核的现有库。
处理边界的另一种方法是在每个方向上将数组扩展一个单元格。这避免了卷积代码中昂贵的分支。
https://stackoverflow.com/questions/2035522
复制相似问题