有没有一种简单的方法可以找到二维数组中元素的邻居(即元素周围的八个元素)?只需在不同的组合中减去和添加索引,如下所示:
array[i-1][i] array[i-1][i-1] array[i][i-1] array[i+1][i]
... 等等.
(伪代码)
row_limit = count(array); if(row_limit > 0){ column_limit = count(array[0]); for(x = max(0, i-1); x <= min(i+1, row_limit); x++){ for(y = max(0, j-1); y <= min(j+1, column_limit); y++){ if(x != i || y != j){ print array[x][y]; } } } }
当然,这需要几乎与原始硬编码解决方案一样多的线路,但有了这个,您可以尽可能多地扩展"邻域"(2-3个或更多单元格)
我认为Ben在他的方法中是正确的,尽管我可能会对其进行重新排序,以改善局部性.
array[i-1][j-1] array[i-1][j] array[i-1][j+1] array[i][j-1] array[i][j+1] array[i+1][j-1] array[i+1][j] array[i+1][j+1]
避免边界检查问题的一个技巧是使数组尺寸2大于所需尺寸.所以,像这样的小矩阵
3 1 4 1 5 9 2 6 5
实际上实现为
0 0 0 0 0 0 3 1 4 0 0 1 5 9 0 0 2 6 5 0 0 0 0 0 0
然后在求和时,我可以在两个维度中从1到3下标,并且上面的数组引用保证有效,并且对最终总和没有影响.我假设c,并且该示例的基于零的下标
@SebaGR的替代方案,如果您的语言支持:
var deltas = { {x=-1, y=-1}, {x=0, y=-1}, {x=1, y=-1}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=1}, {x=0, y=1}, {x=1, y=1} }; foreach (var delta in deltas) { if (x+delta.x < 0 || x + delta.x >= array.GetLength(0) || y+delta.y < 0 || y + delta.y >= array.GetLength(1)) continue; Console.WriteLine("{0}", array[x + delta.x, y + delta.y]); }
可读性略有优势,如果可以静态分配增量,则可能具有性能.
这是来自@seb原始伪代码的一个有效的Javascript示例:
function findingNeighbors(myArray, i, j) { var rowLimit = myArray.length-1; var columnLimit = myArray[0].length-1; for(var x = Math.max(0, i-1); x <= Math.min(i+1, rowLimit); x++) { for(var y = Math.max(0, j-1); y <= Math.min(j+1, columnLimit); y++) { if(x !== i || y !== j) { console.log(myArray[x][y]); } } } }