在二维数组中查找邻居

Emi*_*nsø 24 language-agnostic arrays multidimensional-array

有没有一种简单的方法可以找到二维数组中元素的邻居(即元素周围的八个元素)?只需在不同的组合中减去和添加索引,如下所示:

array[i-1][i]
array[i-1][i-1]
array[i][i-1]
array[i+1][i]
Run Code Online (Sandbox Code Playgroud)

... 等等.

Seb*_*Seb 29

(伪代码)

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];
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

当然,这需要几乎与原始硬编码解决方案一样多的线路,但有了这个,您可以尽可能多地扩展"邻域"(2-3个或更多单元格)

  • 乔尔说,如果你在边缘这样做,没有一些边界检查,当你寻找像数组[-1][4]这样的东西时,你会得到一个索引越界异常。 (2认同)

Evi*_*ach 13

我认为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]
Run Code Online (Sandbox Code Playgroud)

避免边界检查问题的一个技巧是使数组尺寸2大于所需尺寸.所以,像这样的小矩阵

3 1 4
1 5 9
2 6 5
Run Code Online (Sandbox Code Playgroud)

实际上实现为

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 
Run Code Online (Sandbox Code Playgroud)

然后在求和时,我可以在两个维度中从1到3下标,并且上面的数组引用保证有效,并且对最终总和没有影响.我假设c,并且该示例的基于零的下标


Ben*_*n S 5

打印 的邻居L[row][column]

  print(L[row-1][column-1], L[row-1][column], L[row-1][column+1])
  print(L[row][column-1], L[row][column], L[row][column+1])
  print(L[row+1][column-1], L[row+1][column], L[row+1][column+1])
Run Code Online (Sandbox Code Playgroud)

这可能是最快/最简单的方法就是打印可能的邻居。但请确保进行索引越界检查。

有些语言可能提供执行此操作的快捷方式,但我不知道有什么。

  • 但如果该物品位于角落或侧面怎么办?你会如何检查呢? (3认同)

Fry*_*Guy 5

@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]);
}
Run Code Online (Sandbox Code Playgroud)

可读性略有优势,如果可以静态分配增量,则可能具有性能.


小智 5

这是来自@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]);
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)