Ian*_*n P 21 language-agnostic arrays algorithm matrix multidimensional-array
我说有一个二维数组
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
Run Code Online (Sandbox Code Playgroud)
我需要得到与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
Run Code Online (Sandbox Code Playgroud)
谢谢!
Mar*_*ers 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]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果订单很重要,您可以按照您想要的顺序构建所有(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]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
eli*_*ner 12
我可能会为每个方向寻找一个dx,dy的常量列表,如下所示:
struct {
int dx;
int dy;
} directions[] = {{-1,-1,},{-1,0,},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
Run Code Online (Sandbox Code Playgroud)
然后你用一个简单的循环遍历方向:
for (int i = 0; i < 8; i++) {
// use x + directions[i].dx;
// use y + directions[i].dy;
}
Run Code Online (Sandbox Code Playgroud)
您当然可以使用sizeof(directions) / sizeof(directions[1])
而不是8
上述内容.
就个人而言,循环比原始循环更难看.
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 ]
Run Code Online (Sandbox Code Playgroud)
但是,如果没有指定您想要的值,那么您在不同方向上执行的操作意味着您是否希望将值放在单独的变量中.
对于生活方式处理游戏,您通常希望无论如何都要使用位模式,而不是单个值的数组,并且您可以使用累加器和临时值一次水平扫描八个单元格中的三个.对于图形卷积,请使用具有3x3内核的现有库.
处理边界的另一种方法是在每个方向上将数组扩展一个单元.这避免了卷积码中昂贵的分支.