查找数组中元素周围的元素

我有一个多维数组,我想获取该数组中特定元素周围的元素。

例如,如果我有以下内容:

[[1,2,3,4,5,6] [8,9,7,5,2,6] [1,6,8,7,5,8] [2,7,9,5,4,3] [9,6,7,5,2,1] [4,7,5,2,1,3]] 

如何查找上述任何元素周围的所有8个元素? 我如何处理边缘的元素?

我想到的一种方法是,为此编写一个9行代码,这很明显,但是有更好的解决方案吗?

您可以在表单中使用’direction array’

 [[-1,-1], [-1,0],[1,0]..and so on] 

并且采用点坐标并通过方向数组迭代的方法 – >向坐标添加方向数,检查索引不超出范围并收集结果。 像这样的东西:

 private static int[][] directions = new int[][]{{-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0, -1}}; static List getSurroundings(int[][] matrix, int x, int y){ List res = new ArrayList(); for (int[] direction : directions) { int cx = x + direction[0]; int cy = y + direction[1]; if(cy >=0 && cy < matrix.length) if(cx >= 0 && cx < matrix[cy].length) res.add(matrix[cy][cx]); } return res; } 

对于(i,j) – >

  (i - 1, j - 1) (i - 1, j) (i - 1, j + 1) (i, j - 1) (i, j + 1) (i + 1, j - 1) (i + 1, j) (i + 1, j + 1) 

现在,在边缘,你可以检查num % row == 0 ,然后检查它在行边缘…和, num % col == 0然后它的列边缘..

以下是您可以继续的方式: –

给定一个索引(i, j) ..您可以在与j相邻的行中找到i - 1 ,然后是i ,然后是i + 1 。 ( 注意 : – 对于索引i您只需要访问j - 1j + 1

随后您还可以检查row edgecolumn edge

在这里,您可以查看下面的代码,它是如何发生的: –

  // Array size int row = 6; int col = 6; // Indices of concern int i = 4; int j = 5; // To the left of current Column int index = i - 1; for (int k = -1; k < 2; k++) { if (index % row > 0 && ((j + k) % col) > 0) { System.out.println(arr[index][j + k]); } } // In the current Column index = i; // Increment is 2 as we don't want (i, j) for (int k = -1; k < 2; k = k + 2) { if (index % row > 0 && ((j + k) % col) > 0) { System.out.println(arr[index][j + k]); } } // To the right of current Column index = i + 1; for (int k = -1; k < 2; k++) { if (index % row > 0 && ((j + k) % col) > 0) { System.out.println(arr[index][j + k]); } } 

更新 : – 上面的代码可以进一步简化..但我把这个任务留给你.. 提示 : – 你可以从那里减少一个for循环..

 for (i = 0; i < array.length; i++) { for (j = 0; j < array[i].length; j++) { for (x = Math.max(0, i - 1); x <= Math.min(i + 1, array.length); x++) { for (y = Math.max(0, j - 1); y <= Math.min(j + 1, array[i].length); y++) { if (x >= 0 && y >= 0 && x < array.length && y < array[i].length) { if(x!=i || y!=j){ System.out.print(array[x][y] + " "); } } } } System.out.println("\n"); } } 

感谢所有回答的人,但是我在刚刚发现的这篇文章的帮助下想出来,以上是解决方案。 再次感谢 :)

基本情况只是通过索引移位来获得邻居元素。 对于(i,j) ,它将是(i + 1, j)(i - 1, j)等。

在边缘我使用两种方法:

  1. Modulo %运算符可以避免IndexOutOfBoundsexception,但它有时会与错误的元素索引混淆。
  2. 用一层默认元素包裹矩阵。 它为保持矩阵添加了一些额外的空间,但是使代码更具可读性而不会捕获exception,批量等等。 当表示迷宫为矩阵时,经常使用此技巧。

示例:您的默认元素为0。

 0 0 0 0 0 0 0 1 2 3 4 0 0 2 6 7 3 0 0 1 3 5 7 0 0 2 4 6 2 0 0 0 0 0 0 0 

注意:不要忘记迭代实际的数组大小,而不是扩展。

这是我用Ruby编写的问题的解决方案。 不是计算元素是否在边缘,而是可以访问边缘“上方”的元素并处理那里发生的“nil”值或exception。 然后从最终列表中删除“nil”值。 这个解决方案不如计算一些“点”是否超出边缘。

 big_map = [[1,2,3,4,5,6], [8,9,7,5,2,6], [1,6,8,7,5,8], [2,7,9,5,4,3], [9,6,7,5,2,1], [4,7,5,2,1,3]] # monkey patch classes to return nil. [NilClass, Array].each do |klass| klass.class_eval do def [](index) return nil if index < 0 or index > self.size rescue nil self.fetch(index) rescue nil end end end class Array # calculate near values and remove nils with #compact method. def near(i,j) [ self[i - 1][j - 1], self[i - 1][j - 0], self[i - 1][j + 1], self[i - 0][j - 1], self[i - 0][j + 1], self[i + 1][j - 1], self[i + 1][j - 0], self[i + 1][j + 1], ].compact end end puts big_map.near(1,1).inspect # => [1, 2, 3, 8, 7, 1, 6, 8] puts big_map.near(0,0).inspect # => [2, 8, 9] puts big_map.near(5,5).inspect # => [2, 1, 1] 

我正在研究他同样的问题,并提出了一个小的优化解决方案,以找到2D矩阵中任何点的周围数字,希望这有帮助,请评论,如果我可以以某种方式缩短逻辑代码: –

 import java.util.ArrayList; public class test { public static void main(String[] arg){ int[][] arr = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}}; //int[][] arr = {{width,2,3},{4,5,6},{7,8,9}}; ArrayList al = new ArrayList(); int x = 2, y = 2; int width = 2; //change the value of width, according to the requirement for(int i = 0; i < 5; i++){ for(int j = 0; j < 5; j++){ if( (i == (x-width) && ( (y+width) >= j && j >= (y-width))) || (i == (x+width) && ( (y+width) >= j && j >= (y-width))) || (j == (y-width) && ( (x+width) >= i && i >= (x-width))) || (j == (y+width) && ( (x+width) >= i && i >= (x-width))) ){ //if( x >= 0 && i < (i+width) && y >= 0 && j < (j+width)) { al.add(arr[i][j]); } } } } System.out.println(al); } } 

你没有提到你是想要边缘的周期性邻居还是忽略周期性的邻居。 假设你想要周期性的邻居就是代码,

 List getNeighbours(int[][] mat, int x, int y){ List ret = new ArrayList(); int rows = mat.length; int cols = mat[0].length; for(int i=-1,i<=1;i++) for(int j=-1;j<=1;j++) if(i||j) ret = ret.add(mat[(x+i)%rows][(y+j)%cols]); return ret; } 
 (x-1, y-1) -> upper left (x-1, y) -> left (x-1, y+1) -> lower left 

 (x, y+1) -> up (x, y) -> current position (x, y-1) -> down 

 (x+1, y+1) -> upper right (x+1, y) -> right (x+1, y-1) -> lower right 

您可以将此作为指南。 现在你需要做的就是在try catch中添加它们。

  for( int x=0; x